text文本识别html富文本(待改进)
需求
项目里需要将之前外包的h5界面的内容移植到引擎中
前面已经完成了视频的在线播放(uniwebview插件实现),也通过方法查询信息将数据动态的展示在界面中
过程中遇到了一个问题,那就是接口返回的数据里存在html格式的富文本数据,而unity本身能够识别的富文本格式很少,显示到引擎中会出现很多html的标签字符串,看起来十分的不雅观
需要做到的就是在显示之前通过对富文本的处理,显示unity本身能够识别的富文本然后再显示到界面里
逻辑
通过c#先对接收到的富文本字符串进行踹选,去除掉用不了的标签信息,
然后通过xlua对富文本进行识别处理,返回unity能够支持的富文本格式
显示到untiy界面中
实现
由于对前端的知识不是很熟悉,所以在网上找到了一个通过xlua处理html富文本的帖子
链接如下
https://blog.youkuaiyun.com/weixin_45283952/article/details/118571946
有关如何使用xlua这个网上的教程大多都是基础的不能在基础的,看了之后基本没卵用
我总结一下自己用到的方法
xlua的安装
(这个网上还是能找到的),简单的说就是在
github.com/Tencent/xlua/releases
下载xlua,注意,下载2.1.15
配置到unity
把下载的压缩包里的assets里的plguins和Xlua文件导入到unity里
使用
上面提到的通过xlua实现富文本识别的大佬的帖子里只是说明了xlua的内容,具体怎么调用的没有说,我在自己摸索了之后是这么做的
1新建一个lua文件(streamingassets下)
写上下面的代码
`local test = require(“HtmlToLua”)
local testtool = {}
function Test(richText)
local result = “”
result = test:HtmlToLua(richText)
return result
end
`
第一行是在同级目录下引用其他的lua文件
默认的路径是在c#里传入的路径,如果c#里lua文件路径修改了的话,引用的时候路径也需要跟着修改
下面是局部变量可以不写
然后是写一个全局的方法函数,参数写上需要传入的数据名称(自定义)
把第一行引用的lua作为类来调用里面的方法即可
end结束方法
(更多的lua使用可以去找基础的教程)
**其实逻辑就是通过新建一个lua引用已经写好的lua,调用它里面的方法就好了 **
当然这个帖子大佬写的很好(反正我看的不是很懂),只不过功能里没有实现对所有html标签的识别
刚好项目里接收到的数据信息里就有大佬的帖子里没有的标签
所以没办法还是得想办法
首先在看了大佬的xlua之后发现有可以对标签筛选的内容,项目里有一个< strong >的标签,所以就在那里添加了一个对这个标签进行处理的内容
如图
不过这样还不够,项目里的数据还有对< p >进行样式修改的内容(< p style=“text-align:center…”>)
而大佬的方法里好像只做了对span标签里颜色和大小样式的处理,没有做其他的更多操作
改进优化(待改进)
由于对前端和lua都不太熟悉,所以想到的办法就是先在C#里对数据进行处理,去掉这些处理不了的样式,像居中的效果在unity的text也能做到
所以干脆就这么办了
通过对数据的分析发现样式的字符串附近会有"和空格,
通过string.split函数拆开字符串,然后处理判断一下,生成新的字符串,把这个字符串传给xlua解析
具体的方法如下
string[] parames = exText.Split('"');//exTExt就是原始的html富文本字符串
string first = "";
int index = 0;
foreach (string parame in parames)
{
if (index%2==0)
{
if (parame.Contains(" "))
{
string[] parames2 = parame.Split(' ');
first += parames2[0];
}else first += parame;
}
index++;
}
这个方法就相对比较死,在目前的阶段能用,如果后面接口里返回更多的样式和标签的话,还得对他进行更多的判断处理
看后面有没有时间研究一下吧
c#完整代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using XLua;
public class RichTextDemo : MonoBehaviour
{
public Text text;
public delegate string Test(string richText);
// Start is called before the first frame update
void Start()
{
LuaEnv luaEnv = new LuaEnv();
luaEnv.AddLoader(myLoader);
string text1 = "<p><br/></p><p style=\"text-align: center;\"><strong>课程介绍</strong></p><p><strong><br/></strong></p><p style=\"text-align: center;\">一起来创作吧~</p>";
luaEnv.DoString("require 'main'");
Test func1 = luaEnv.Global.Get<Test>("Test");
string exText = text1;
//手动去掉style样式的方法
string[] parames = exText.Split('"');
string first = "";
int index = 0;
foreach (string parame in parames)
{
if (index%2==0)
{
if (parame.Contains(" "))
{
string[] parames2 = parame.Split(' ');
first += parames2[0];
}else first += parame;
}
index++;
}
Debug.Log(first);
text.text = func1(first);
}
public byte[] myLoader(ref string filePath)//这个是很多教程里都涉及到的访问路径,有不理解的可以看看其他的lua基础帖子
{
string path = Application.streamingAssetsPath+"/"+ filePath + ".lua";
return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(path));
}
}
这次对lua的二次接触发现之前学xlua热更新的还是太皮毛了,最近在看b站大佬刚出的xlua热更新的视频,里面说了ab包和代码热更的具体操作,加油吧,链接送上
https://www.bilibili.com/video/BV1xv411G77U/
同天下午更新一下
发现一个小bug
如果字符串里在非p标签里出现了空格(比如
123 123123
)的话是会报错的因为按照上面的逻辑是有问题的,所以下午改进了一下对字符串的处理
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using XLua;
public class AnalysisHtml5Tools : MonoBehaviour
{
public delegate string AnalysisRichText(string richText);
// Start is called before the first frame update
void Start()
{
}
/// <summary>
/// 解析html富文本的方法
/// </summary>
/// <param name="richText">html富文本字符串</param>
/// <returns>解析后字符串</returns>
public string AnalysisRichTextMethod(string richText)
{
LuaEnv luaEnv = new LuaEnv();
luaEnv.AddLoader(myLoader);
//string text1 = "<p><br/></p><p style=\"text-align: center;\"><strong>课程介绍</strong></p><p><strong><br/></strong></p><p style=\"text-align: center;\">一起来创作吧~</p>";
luaEnv.DoString("require 'main'");
AnalysisRichText func1 = luaEnv.Global.Get<AnalysisRichText>("Test");
//去掉开头的换行
//richText = richText.Substring(11);
//string exText = richText;
//手动去掉style样式的方法
string[] parames = richText.Split('"');
int index = 0;
string tem = "";
foreach (string parame in parames)
{
if (index % 2 == 0 && !parame.Contains("text"))
{
tem += parame;
}
}
//去掉style=
string[] tem1 = tem.Split(' ');
string tem2 = "";
foreach (string parame in tem1)
{
if (parame.Contains("style"))
{
tem2 += parame.Substring(parame.IndexOf("style") + 6, parame.Length - 6);
}
else tem2 += parame;
}
string luaText = func1(tem2);
return luaText;
}
public byte[] myLoader(ref string filePath)
{
string path = Application.streamingAssetsPath + "/" + filePath + ".lua";
return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(path));
}
}
逻辑就是先通过字符判断把样式里的关键词捉出来然后去掉,保证不影响后面即可
然后才是对样式关键词的捕捉和去除