【问题标题】:regex insert tag surrounding all digits正则表达式插入所有数字周围的标签
【发布时间】:2020-08-20 09:31:27
【问题描述】:

我有一个包含许多这样的行的文档:

<tr><td width="10%">doc_no_320F0321</td><td width="5%">116</td><td> bla bla bla 1976, bla bla point (2) bla bla bla. </td><td> bla bla bla 1976, bla bla point (1) bla bla bla. </td></tr>

(美化后它看起来像这样:

<tr>
    <td width="10%">doc_no_320F0321</td>
    <td width="5%">116</td>
    <td> bla bla bla 1976, bla bla point (2) bla bla bla. </td>
    <td> bla bla bla 1976, bla bla point (1) bla bla bla. </td>
</tr>

)

我需要做的是检查第三个和第四个的数字是否相同,忽略其他字符。

为此,我尝试用 突出显示它们,以便更容易看到它们。 我正在运行这个 sed 替换:

sed -i -r 's|(<td>.*?)([[:digit:]]+)(.*?<\/td>)|\1<mark>\2<\/mark>\3|g'

但它只围绕每行的最后一位数字

有人可以帮我把第三个和第四个标签中的所有数字组合括起来吗?

谢谢。

【问题讨论】:

  • 如果只需要匹配数字,为什么要提前突出显示?如果您的正则表达式可以很好地检测到它们,您可以向它们添加mark,为什么您需要标记它们?
  • 哦,那一点都不清楚,对不起。当我说“匹配”时,我的意思是“确保它们同时存在于 中”,而不是“能够使用正则表达式找到它们”。那里的术语有误...谢谢,我将进行编辑以使其更清晰。
  • Parsing HTML with regex is a hard job HTML 和正则表达式不是好朋友。使用解析器,它更简单、更快且更易于维护。见:php.net/manual/en/class.domdocument.php

标签: html regex sed


【解决方案1】:

在任意 HTML 上使用正则表达式是个坏主意,因为 SGML 不是正则。您需要一个 HTML 解析器才能正确执行此操作:

解析。找到 TR 的第三个和第四个 TD 子代,并更改它们的文本子代。

如果幸运的话,您可以通过在正则表达式中转换和计算 TD 之前不美化整行来避免解析已知的 HTML。

(&lt;tr[^&lt;]+&lt;td[^&lt;]+&lt;td[^&lt;]+&lt;td[^"]"\D*)(\d+)([^"]....)

\1&lt;mark&gt;\2&lt;/mark&gt;\3

第四次也是如此。

但是当您的文本有多个要“标记”的数字块时,您会遇到问题。

【讨论】:

    【解决方案2】:

    如果您只想生成页面的 HTML 版本,并在特定列中突出显示数字,您可以执行以下操作:

    $d = new DOMDocument();
    $d->loadHTMLFile('your_file_path.html');
    
    $x = new DOMXpath($d);
    $third_td = $x->evaluate('//tr/td[3]');
    $fourth_td = $x->evaluate('//tr/td[4]');
    
    $pattern = '/\d/';
    $replace = '<span style="color: red;">${0}</span>';
    
    foreach ( $third_td as $key => $input ) {
        $input->nodeValue = preg_replace($pattern, $replace, $input->nodeValue);
        $fourth_td[$key]->nodeValue = preg_replace($pattern, $replace, $fourth_td[$key]->nodeValue);
    }
    
    echo $d->saveHTML();
    

    $d-&gt;saveHTML() 的结果是一个 HTML 版本,其中第 3 列和第 4 列中的所有数字都以红色着色。如果这是您需要的,可以相应地更改样式。

    我没有考虑处理任何可能导致错误的缺失列或其他不兼容问题。

    这段代码是用 PHP 编写的,基于 @Toto 的建议。

    希望对你有帮助

    【讨论】:

      【解决方案3】:

      sed 和一行中的每一行你可能会很幸运

      sed -r ':a;s#(.*</td>)(.*<td>)(.*[^\r[:digit:]])([[:digit:]]+)#\1\2\3<mark>\r\4</mark>#;ta;s/\r//g'
      

      你不应该用sed解析HTML,所以这个解决方案不值得解释。

      【讨论】:

        猜你喜欢
        相关资源
        最近更新 更多
        热门标签