[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 }

结果:

猜你喜欢

转载自www.cnblogs.com/lyh916/p/9160381.html
今日推荐