V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
leoleoasd
V2EX  ›  程序员

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

  •  
  •   leoleoasd ·
    leoleoasd · 2018-09-23 12:55:46 +08:00 · 3282 次点击
    这是一个创建于 2013 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    替换为

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

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

    16 条回复    2018-09-24 11:06:19 +08:00
    leoleoasd
        1
    leoleoasd  
    OP
       2018-09-23 13:02:01 +08:00
    不是正则替换 弄个别的小程序替换也可以

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

    你可以理解为我们需要进行 html 中的文本替换 把除了标签之外的文本全部用 @lang 包裹
    Guaidaodl
        4
    Guaidaodl  
       2018-09-23 13:45:50 +08:00
    正则表达式不足以精确分析 HTML 格式的文本. 不过你如果想要简单应该可以用 "<[^>]+>\s*([^<]+)" 捕获非标签部分内容.
    这个表达式对空格和换行的处理不够友好. 建议用程序辅助一下, 写太复杂的正则表达式可能会遇到性能问题, 也不太好维护.
    SakuraSa
        5
    SakuraSa  
       2018-09-23 14:53:20 +08:00
    既然用 python 了,直接用 html 解析库(例如 bs4 )会方便很多
    解析后遍历整个元素树,替换,然后再序列化回 html
    zjsxwc
        6
    zjsxwc  
       2018-09-23 15:06:55 +08:00 via Android   ❤️ 1
    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
        7
    wizardforcel  
       2018-09-23 17:32:53 +08:00
    随便找个 XML 解析库,然后提取里面的所有文本节点。就行了。

    不过这样可能翻译得支离破碎的,比如这个“前文本<a ...>链接</a>后文本”。
    fox0001
        8
    fox0001  
       2018-09-23 18:26:07 +08:00 via Android
    与其费神写个复杂的正则表达式,还不如直接 dom 解析
    DavidNineRoc
        9
    DavidNineRoc  
       2018-09-23 18:29:42 +08:00
    建议使用 phpquery 先查找匹配出来,然后遍历所有节点,直接字符串替换用不到正则
    billlee
        10
    billlee  
       2018-09-23 20:04:54 +08:00
    还是用 sax 解析器吧
    panpanpan
        11
    panpanpan  
       2018-09-23 20:36:44 +08:00 via iPhone
    为什么不换个思路把 @lang(123) 扩展为 @lang('en',123) 和 @lang('zh',123)
    leoleoasd
        12
    leoleoasd  
    OP
       2018-09-23 21:06:10 +08:00
    @panpanpan #11 @lang 会 根据设置的语言 自动在翻译文件中查找翻译 显示
    这是 html 模板
    kawkeye
        13
    kawkeye  
       2018-09-23 21:48:14 +08:00
    我还是不能理解,用正则是匹配到特征项然后加上函数么
    buliugu
        14
    buliugu  
       2018-09-23 21:51:34 +08:00
    这不是国际化吗,i18n 了解一下
    leoleoasd
        15
    leoleoasd  
    OP
       2018-09-24 09:07:54 +08:00
    @kawkeye #13 只是需要把所有文字都用翻译函数包裹 可以不用正则
    Droi
        16
    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
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1343 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 17:43 · PVG 01:43 · LAX 10:43 · JFK 13:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.