zoukankan      html  css  js  c++  java
  • [UGUI]图文混排(一):标签制定和解析

    参考链接:

    https://github.com/SylarLi/RichText/tree/master/Assets/Scripts

    正则表达式:

    https://blog.csdn.net/lyh916/article/details/49201195

    图文混排主要用于聊天,其实就是传输某种格式的字符串,然后解析这个字符串,生成表情文字等。图文混排的第一步,就是确定好格式,这里使用html的标签格式,对于代码中出现的start和end字段可以先忽略。标签格式如下:

    <material=underline c=#ffffff h=1 n=*** p=***>blablabla...</material>

    RichTextTag.cs

     1 //标签类型
     2 public enum RichTextTagType
     3 {
     4     None,
     5     Underline,      //下划线
     6 }
     7 
     8 //标签基类
     9 public abstract class RichTextTag
    10 {
    11     public int start;
    12     public int end;
    13     public abstract RichTextTagType tagType { get; }
    14 
    15     public abstract void SetValue(string key, string value);
    16 }

    RichTextUnderlineTag.cs

     1 using UnityEngine;
     2 
     3 //下划线标签
     4 public class RichTextUnderlineTag : RichTextTag {
     5 
     6     public Color color = Color.white;//颜色
     7     public float height = 1f;//高度
     8     public string eventName;//事件名
     9     public string eventParameter;//事件参数
    10 
    11     public override RichTextTagType tagType { get { return RichTextTagType.Underline; } }
    12 
    13     public override void SetValue(string key, string value)
    14     {
    15         switch (key)
    16         {
    17             case "c":
    18                 {
    19                     ColorUtility.TryParseHtmlString(value, out color);
    20                     break;
    21                 }
    22             case "h":
    23                 {
    24                     float.TryParse(value, out height);
    25                     break;
    26                 }
    27             case "n":
    28                 {
    29                     eventName = value;
    30                     break;
    31                 }
    32             case "p":
    33                 {
    34                     eventParameter = value;
    35                     break;
    36                 }
    37             default:
    38                 break;
    39         }
    40     }
    41 }

    RichTextTagParser.cs

     1 using System.Text.RegularExpressions;
     2 
     3 //解析一条标签:<material xxx>
     4 public class RichTextTagParser {
     5 
     6     private static readonly Regex tagRegex = new Regex(@"<material=([^>s]+)([^>]*)>");//(标签类型)(标签参数)
     7     private static readonly Regex paraRegex = new Regex(@"(w+)=([^s]+)");//(key)=(value)
     8     public string content;//<material=xxx xxx>
     9     public int start;
    10     public int end;
    11 
    12     public RichTextTag Parse()
    13     {
    14         RichTextTag tag = null;
    15         Match match = tagRegex.Match(content);
    16         if (match.Success)
    17         {
    18             string tagName = match.Groups[1].Value;//标签类型
    19             if (!tagName.StartsWith("#"))
    20             {
    21                 var keyValueCollection = paraRegex.Matches(match.Groups[2].Value);//标签参数
    22                 switch (tagName)
    23                 {
    24                     case "underline":
    25                         {
    26                             tag = new RichTextUnderlineTag();
    27                             break;
    28                         }
    29                     default:
    30                         break;
    31                 }
    32                 if (tag != null)
    33                 {
    34                     tag.start = start;
    35                     tag.end = end;
    36                     for (int i = 0; i < keyValueCollection.Count; i++)
    37                     {
    38                         string key = keyValueCollection[i].Groups[1].Value;
    39                         string value = keyValueCollection[i].Groups[2].Value;
    40                         tag.SetValue(key, value);
    41                     }
    42                 }
    43             }
    44         }
    45         return tag;
    46     }
    47 }

    RichTextParser.cs

     1 using System.Collections.Generic;
     2 using System.Text.RegularExpressions;
     3 
     4 //解析全部标签
     5 public class RichTextParser {
     6 
     7     private static readonly Regex regex = new Regex(@"</*material[^>]*>");//<material xxx> or </material>
     8     private const string endStr = "</material>";
     9 
    10     private Stack<RichTextTagParser> tagParserStack;
    11     private List<RichTextTag> tagList;
    12 
    13     public RichTextParser()
    14     {
    15         tagParserStack = new Stack<RichTextTagParser>();
    16         tagList = new List<RichTextTag>();
    17     }
    18 
    19     public void Parse(string richText, out List<RichTextTag> tags)
    20     {
    21         tagParserStack.Clear();
    22         tagList.Clear();
    23         Match match = regex.Match(richText);
    24         while (match.Success)
    25         {
    26             if (match.Value == endStr)
    27             {
    28                 if (tagParserStack.Count > 0)
    29                 {
    30                     RichTextTagParser tagParser = tagParserStack.Pop();
    31                     tagParser.end = match.Index - 1;
    32                     if (tagParser.end >= tagParser.start)
    33                     {
    34                         RichTextTag tag = tagParser.Parse();
    35                         if (tag != null)
    36                         {
    37                             tagList.Add(tag);
    38                         }
    39                     }
    40                 }
    41             }
    42             else
    43             {
    44                 RichTextTagParser tagParser = new RichTextTagParser();
    45                 tagParser.content = match.Value;
    46                 tagParser.start = match.Index + match.Length;
    47                 tagParserStack.Push(tagParser);
    48             }
    49             match = match.NextMatch();
    50         }
    51         tags = tagList;
    52     }
    53 }

    测试如下:

     1 using UnityEngine;
     2 using System.Collections.Generic;
     3 
     4 //下划线<material=underline c=#ffffff h=1 n=*** p=***>blablabla...</material>
     5 public class RichTextTest : MonoBehaviour {
     6 
     7     private string a = @"123<material=underline c=#ff0000 h=1 n=name1 p=para1>blablabla...</material>qwe" +
     8         @"<material=underline c=#00ff00 h=2 n=name2 p=para2>blablabla...</material>asd";
     9     private List<RichTextTag> tagList;
    10 
    11     private void Start()
    12     {
    13         RichTextParser parser = new RichTextParser();
    14         parser.Parse(a, out tagList);
    15         for (int i = 0; i < tagList.Count; i++)
    16         {
    17             RichTextUnderlineTag tag = tagList[i] as RichTextUnderlineTag;
    18             Debug.Log(tag.color);
    19             Debug.Log(tag.height);
    20             Debug.Log(tag.eventName);
    21             Debug.Log(tag.eventParameter);
    22         }
    23     }
    24 }

    结果:

  • 相关阅读:
    我的DBA之路:MYSQL数据类型
    我的DBA之路:MYSQL架构
    我的DBA之路:安装MySQL
    Java多线程系列之:显示锁
    Java多线程系列之:原子操作CAS
    Java多线程系列之:线程的并发工具类
    Java并发AQS原理分析(二)
    Java并发AQS原理分析(一)
    MySQL聚集索引和非聚集索引
    快速失败机制--fail-fast
  • 原文地址:https://www.cnblogs.com/lyh916/p/9160381.html
Copyright © 2011-2022 走看看