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

请教大家一个复杂的正则表达式的问题,即如何匹配 Markdown 文件中嵌套的 HTML 表格中的 Markdown 语法的链接和加粗内容。

  •  
  •   myscarh · 2020-02-03 01:58:57 +08:00 · 2362 次点击
    这是一个创建于 1756 天前的主题,其中的信息可能已经有所发展或是发生改变。
    目标 Markdown 文件是类似这样的:

    <td sda> sdfsdf
    //不能被匹配的单元格
    wee</td>
    <td sdff>sdfsdfsdf
    ** 需要被匹配的粗体**
    sd[需要被匹配的链接]( http)sdfsd
    两边有空格
    <p>其他 HTML 标签 <br/>abc</p>
    </td>
    </table>
    ## Markdown 语法的部分
    [不能被匹配的链接]( http)
    **不能被匹配的粗体**
    <table>
    <th>aa</th
    <td> sdfsdf 不能被匹配的单元格 sdfsdf
    wee</td>
    <td> sdfsdf 不能被匹配的单元格 sdfsdf

    wee</td>
    <td> ** 需要被匹配的粗体**
    sd[需要被匹配的链接]( http)sdfsdsdfsdf
    <p> 其他 HTML 标签 <br/>abc </p>
    </td>
    <td sdff>sdfsdfsdf

    //不能被匹配的单元格
    <b>asdasd</b>
    </td>


    要求是不能匹配没有 Markdown 加粗或链接的 HTML 单元格,而且返回结果除了<td, </td>, [, ], (和)以外必须被分组捕捉以用于批量替换。
    可以一次只匹配一个单元格中的一个 Markdown 链接或加粗内容,然后多次替换来解决,但是 HTML 表格之外的 Markdown 链接不能被匹配。
    我之前尝试用<td([^>]*?)>([\s\S]*?)\[(.*?)\]\((.*?)\)([\s\S]*?)<\/td>替换成<td$1>$2<a href="$4">$3</a>$5</td>,但是([\s\S\n]*?)会匹配表格外的内容。
    目前看难点在于如何匹配<td([^>]*?)>和\[(.*?)\]\((.*?)\)之间所有内容(包括换行和空格),如果存在</td>则不匹配该单元格

    请问该使用什么样的正则表达式。
    10 条回复    2020-02-04 05:42:12 +08:00
    zhuangzhuang1988
        1
    zhuangzhuang1988  
       2020-02-03 02:11:33 +08:00
    应该得用上下文无关文法(CFG)吧
    noqwerty
        2
    noqwerty  
       2020-02-03 02:36:01 +08:00 via Android
    这种情况用 html parser 会比正则省很多脑细胞😂
    wwcchn9
        3
    wwcchn9  
       2020-02-03 02:38:34 +08:00   ❤️ 1
    理论上来讲,regex 就没有足够的能力 parse CFL,为啥不用 CFG 呢?
    xupefei
        4
    xupefei  
       2020-02-03 02:48:57 +08:00
    状态机……
    laminux29
        5
    laminux29  
       2020-02-03 09:43:52 +08:00
    正则从理论上来说就是大幅度压缩代码。

    一些简单的逻辑,用正则没问题,但太复杂的逻辑,压缩成正则后,可读性、可改性以及可调试性都变得很差。

    建议复杂的情况,老老实实写代码,不要用正则。
    hakono
        6
    hakono  
       2020-02-03 09:58:49 +08:00 via Android
    搞不懂楼主为什么一定要用正则去匹配,纯粹给自己找麻烦
    用 dom 解析器配合 css 选择器选出需要的 html 标签然后用简单的正则把里面需要的文本提取出来不就行了
    Kirscheis
        7
    Kirscheis  
       2020-02-03 10:48:48 +08:00 via Android
    计算机科学小常识:不要用正则去处理 HTML,除非是在写那种用完一两次就可以丢掉的爬虫脚本之类的东西
    autoxbc
        8
    autoxbc  
       2020-02-03 15:05:34 +08:00
    每次你用正则处理序列化的结构数据,就是重新写了一遍这种数据结构的解析器
    wwcchn9
        9
    wwcchn9  
       2020-02-04 02:15:29 +08:00
    @laminux29 扯淡,正则就不足够 parse CFL 是编译原理 101 教的吧。并不是所谓的大幅度压缩代码
    laminux29
        10
    laminux29  
       2020-02-04 05:42:12 +08:00
    @wwcchn9 我说的是能大幅度压缩代码,不是说所有代码都能被压缩成正则。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2658 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 05:12 · PVG 13:12 · LAX 21:12 · JFK 00:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.