求助 正则表达式替换 html 中文字

2018-09-23 12:55:46 +08:00
 leoleoasd

正在给一个写好的模板 加入翻译功能 希望的效果是把

<p>
    <div>
        123
        <a href="foobar">234</a>
    </div>
</p>

替换为

<p>
    <div>
    	@lang("123")
        <a href="foobar">@lang("234")</a>
    </div>
</p>

正则表达式可以做到么?需要一个能在 idea 里正则替换的表达式

3389 次点击
所在节点    程序员
16 条回复
leoleoasd
2018-09-23 13:02:01 +08:00
不是正则替换 弄个别的小程序替换也可以

目前的想法是写个 python 程序 解析 dom 递归把每个元素里的文字都替换后再返回去生成 html
molvqingtai
2018-09-23 13:27:19 +08:00
是要实现多语言站点还是,单纯翻译,只是翻译的话直接用翻译接口发送整个 HTML 就好了
leoleoasd
2018-09-23 13:34:49 +08:00
@molvqingtai #2 跟翻译没关系 翻译我们会自己写
需要的是在 php 的模板中调用翻译

你可以理解为我们需要进行 html 中的文本替换 把除了标签之外的文本全部用 @lang 包裹
Guaidaodl
2018-09-23 13:45:50 +08:00
正则表达式不足以精确分析 HTML 格式的文本. 不过你如果想要简单应该可以用 "<[^>]+>\s*([^<]+)" 捕获非标签部分内容.
这个表达式对空格和换行的处理不够友好. 建议用程序辅助一下, 写太复杂的正则表达式可能会遇到性能问题, 也不太好维护.
SakuraSa
2018-09-23 14:53:20 +08:00
既然用 python 了,直接用 html 解析库(例如 bs4 )会方便很多
解析后遍历整个元素树,替换,然后再序列化回 html
zjsxwc
2018-09-23 15:06:55 +08:00
htmlparser 加上一个递归函数就可以解决楼主的需求。

伪代码:

function convert(dom)
{
if (dom.children.length == 0) {
var textContent = dom.textContent;
if (checkContainChinese(textContent))
dom.textContent = '@lang(' + textContent + ')';
return;
}
dom.children.each( childDom => convert(childDom));
}
convert(parse(html));
wizardforcel
2018-09-23 17:32:53 +08:00
随便找个 XML 解析库,然后提取里面的所有文本节点。就行了。

不过这样可能翻译得支离破碎的,比如这个“前文本<a ...>链接</a>后文本”。
fox0001
2018-09-23 18:26:07 +08:00
与其费神写个复杂的正则表达式,还不如直接 dom 解析
DavidNineRoc
2018-09-23 18:29:42 +08:00
建议使用 phpquery 先查找匹配出来,然后遍历所有节点,直接字符串替换用不到正则
billlee
2018-09-23 20:04:54 +08:00
还是用 sax 解析器吧
panpanpan
2018-09-23 20:36:44 +08:00
为什么不换个思路把 @lang(123) 扩展为 @lang('en',123) 和 @lang('zh',123)
leoleoasd
2018-09-23 21:06:10 +08:00
@panpanpan #11 @lang 会 根据设置的语言 自动在翻译文件中查找翻译 显示
这是 html 模板
kawkeye
2018-09-23 21:48:14 +08:00
我还是不能理解,用正则是匹配到特征项然后加上函数么
buliugu
2018-09-23 21:51:34 +08:00
这不是国际化吗,i18n 了解一下
leoleoasd
2018-09-24 09:07:54 +08:00
@kawkeye #13 只是需要把所有文字都用翻译函数包裹 可以不用正则
Droi
2018-09-24 11:06:19 +08:00
正则可以做到,但有点复杂。下面的方法只对你这个例子起做用。
在真实环境下还要再改改。

perl -p -i -e 's/((?<=\s)\d\d\d|(?<=>)\d\d\d(?=<))/\@lang("$1")/g' file

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/491917

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX