参考链接:
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 }
结果:
原文:https://www.cnblogs.com/lyh916/p/9160381.html