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

把 HTML 中混着的 URL 转成<a>标签,各位有什么优雅的实现方法吗?

  •  
  •   mashirozx · 2022-05-31 03:44:23 +08:00 · 1601 次点击
    这是一个创建于 940 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前提:HTML 原来就包括一些<a>标签和<img>标签,现在要做的是把剩下的不在任何标签内的 URL 转为<a>标签。

    尝试过写正则,反向匹配所有满足条件的,但是太复杂,遂放弃。

    最后考虑先把标签内的 URL 转义,然后替换剩下的所有 URL ,最后再把转义的转回来,代码如下:

    但是真的太丑了,而且存在明显的 bug ,无奈又想不出别的办法,还望大佬们给点思路

    8 条回复    2022-05-31 08:14:01 +08:00
    vance123
        1
    vance123  
       2022-05-31 04:11:15 +08:00 via Android
    先解析成 Dom ,然后再用正则替换文本怎么样
    GeruzoniAnsasu
        2
    GeruzoniAnsasu  
       2022-05-31 04:35:33 +08:00
    ruby 不熟,库就更不了解了

    你需要一个 dom visitor ,然后遍历每个节点,把节点里的 text 正则替换成<a>
    Girlphobia
        3
    Girlphobia  
       2022-05-31 04:54:15 +08:00 via Android
    首先解析 DOM ,然后对 DOM tree 递归遍历节点:
    如果是 <a> ,跳过当前节点及所有子节点;
    如果是 Text ( https://developer.mozilla.org/en-US/docs/Web/API/Text ) ,匹配 URL 正则,替换为 <a> (这里的替换实现细节可以取决于 URL 是可信的还是用户提供的,可能需要考虑 input sanitization );
    如果是其他元素,用以上逻辑递归处理所有子元素。
    wd
        4
    wd  
       2022-05-31 07:17:29 +08:00 via iPhone
    你把 html 解析成 document 之后,应该就可以直接替换所有 text 里面的 url 了吧?
    ho121
        5
    ho121  
       2022-05-31 07:26:39 +08:00 via Android
    如果有 inline 的元素,比如
    <p>http<span>://</span>www.qq.com</p>
    这种的,页面上看起来是连续的内容,实际 Dom 树是有层级的,这种还不太好处理
    xiangyuecn
        6
    xiangyuecn  
       2022-05-31 07:44:37 +08:00
    有多难,还解析 dom ?

    1. 直接取出 body ,过滤掉 head 干扰
    2. 换行符全部用占位符替换掉,比如" __换行__ " 这种不容易冲突的(首尾带空格),转成单行
    3. 替换掉所有 <.*?> 包裹的内容,用占位符替换掉,内容存入 map ,比如 " __替换:123__ "(首尾带空格),map[123]="<替换掉的内容>"
    4. 剩下的文本不就随便你搞了,全是纯的文本节点,简单的一个正则就能完成替换工作
    5. 恢复占位符对应的内容

    性能消耗完全可以忽略不计
    GeruzoniAnsasu
        7
    GeruzoniAnsasu  
       2022-05-31 07:54:08 +08:00
    @xiangyuecn

    <pre> if (a <=3 || a > 5) </pre>
    xiangyuecn
        8
    xiangyuecn  
       2022-05-31 08:14:01 +08:00
    @GeruzoniAnsasu 并不影响,后面会恢复回来。url 的匹配不容易误杀,url 没有空格
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2995 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 14:37 · PVG 22:37 · LAX 06:37 · JFK 09:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.