Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

通过正则实现后台文本可配置化(简易版) #56

Open
liangbus opened this issue Aug 5, 2022 · 1 comment
Open

通过正则实现后台文本可配置化(简易版) #56

liangbus opened this issue Aug 5, 2022 · 1 comment

Comments

@liangbus
Copy link
Owner

liangbus commented Aug 5, 2022

需求点

弹窗内容需要配置化

分析

弹窗文本内容需要做到部分内容高亮,变量(商品名等)替换,自定义跳转链接等

想法

尽量灵活配置化,那就尽可能将输入的内容,排版,变量位置等交给用户处理,因此首先想到的是通过正则去匹配提取用户输入的内容

针对需求的功能要求,主要分为几个步骤进行

  1. 过滤危险标签(XSS攻击,直接删除内容)
  2. 高亮指定文本
  3. 提取链接文本及链接内容
  4. 变量替换

其中第一点业务无关,因为替换的内容会直接以 html 形式插入 DOM 结构中,避免 xss 攻击,因此需要去除脚本内容
其他三点,顺序无强制要求

实现

这里再次贴一下我个人认为学习正则很友好的两个网站(已向身边无数同事安利)
reg101
learn-regex

接下来就是按步骤拆解实现

  1. 我们的目标是去掉 script 标签及其内容,那就是匹配出 <script> 及中包裹的内容即可,考虑到高级浏览器会自动补全 html 标签,针对 script 起始的内容,后续没有闭合标签的,也一并删除,经调试得出正则规则如下
const MATCH_SCRIPTS = /<script(>|)(?<=<script).*?(?=<\/script>)<\/script>|<script(>|).*?(<\/.*>|$)/gm;
  1. 处理高亮内容,因为文本某些内容需要高亮突出,为了灵活应用,用户使用指定符号包裹内容即可,这里使用的双中括号包裹,正则规则如下
const MATCH_HIGHLIGHT_CONTENT = /\[{2}.*?\]{2}/gm;

值得注意的是,双括号包裹的内容,是允许出现单个中括号的,即 []

  1. 提取链接及链接的文本,这里其实分了两个步骤,第一步是提取文本及其链接,然后再把文本和链接区分开,再用 标签拼接起来,链接校验只做了 http 或者 https 的判断
const MATCH_CONTENT_LINKS = /(?<name>\[[^\\[\]]+\](?=\(.+\)))\(.*?\)/gm;
const MATCH_BRACKET_CONTENT = /(?<=\()http(s|).*?(?=\))/gm;

const reg = MATCH_BRACKET_CONTENT;
// RegExp exec 执行完之后,lastIndex 会保留,要重新执行的话,需要手动重置
reg.lastIndex = 0;
const matchUrlRes = reg.exec(curMatch);

if (matchUrlRes && matchUrlRes[0]) {
  return `<a class="link-text" href="${matchUrlRes[0]}">${matchSubStr.replace(/(\[|\])|(\(.*?\))/g, '')}</a>`;
}
  1. 变量替换,这一步就简单了,直接把对应的内容替换成指定的值即可,变量都需要提前预埋好,这不展开说明

String.prototype.replace 方法,第二个参数可以传入一个函数作为处理,以上所有的步骤均通过 replace 的函数操作实现

附:

// 以下正则规则意思为:匹配任意字符,直到命中下一次规则为止
.*?

Thats all.

@liangbus
Copy link
Owner Author

经过一轮测试发现,在 IOS 端,无论是 App 内嵌的 webview 还是浏览器访问的 web 页面,均出现异常(无明确的报错信息,脚本终止执行)

经排查发现是,IOS 系统不支持零宽断言,初步判断是在解析脚本时就报异常,因为存在没有引用该正则的页面也出现了异常

网上粗略搜了下,很多人有遇到过同样的问题,没有太好的解决方案,只能换种写法,多处理一下
image

BTW,安卓端及 PC 端模拟器一切正常,不考虑移动端环境的话,上述正则仍可正常使用

@liangbus liangbus added the 兼容性 Compatible label Aug 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant