包含换行符时,正则表达式不会产生匹配项

时间:2019-02-03 20:49:44

标签: regex sed grep

我正在尝试使用sed或grep解析页面https://extensions.typo3.org/extension/tt_news/的版本号和相应的日期。 更具体地说,我对以下html部分感兴趣:

            <tr>
                <td class="align-middle">
                    <strong>3.6.0</strong> /
                    <span class="ter-ext-state-beta">beta</span>
                    <br />
                    <small>
                        April 06, 2014
                    </small>
                </td>
                <td class="align-middle">
                    tt_news for TYPO3 4.5 - 6.2 (compatibility update)
                </td>
                <td class="align-middle">

                        <strong>4.5.0 - 6.2.99</strong>

                </td>
                <td class="align-middle">

                            <a class="btn btn-primary" title="Size: 2.58MB" href="/extension/download/tt_news/3.6.0/zip/">
                                <strong>
                                    Download ZIP Archive
                                </strong>
                            </a>

                </td>
            </tr>

我想从每个部分中获取版本(在 strong 标记之间)和日期(在 small 标记之间)。 到目前为止,我所有的尝试都失败了,我可以将问题缩小到非常简单的程度。 我已经测试了以下正则表达式,该正则表达式仅尝试在regex101.com上获取 tr 标记,后跟空格和 td 标记,在那里,它工作得很好:

<tr>\s*<td

它给了我5次正确的比赛。以下一项也可以正常工作:

 <tr[^>]*>\s*<td

它产生38个结果,因为它包含具有css class属性的那些tr标记。 但是,无论是grep还是sed都无法使它正常工作。一旦包含\ s,就不再有任何匹配项。看起来像这样:

cat tt_news_history | grep '<tr>\s*<td'

没有点击。

cat tt_news_history | grep '<tr>'

6次点击。

cat tt_news_history | grep '<tr[^>]*>'

很多点击(未计算)。与sed相同。 我究竟做错了什么?为什么不能使用\ s? 感谢您的提示。

1 个答案:

答案 0 :(得分:2)

GNU grep有一个-z选项,可使\s匹配输入中的换行符,例如:

cat tt_news_history | grep -z '<tr>\s*<td'

信息文档中的相关片段:

  

“-z”“-空数据”        将输入和输出数据视为行序列,每行终止        用零字节(ASCII NUL字符)代替换行符。        像“ -Z”或“ --null”选项一样,该选项可与        诸如“ sort -z”之类的命令来处理任意文件名。

     

(...)

     
      
  1. 如何匹配线段?
  2.   
     

标准grep无法执行此操作,因为它基本上是基于行的。   因此,仅使用“ [:space:]”字符类是不匹配的   以您可能期望的方式换行。

     

使用GNU的“ grep”选项“ -z”(“-null-data”),每个输入“行”为   以一个空字节终止; *注意其他选项::。因此,您可以匹配   输入中的换行符,但通常如果匹配则整个   输入是输出,因此这种用法通常与   输出抑制选项,例如“ -q”,例如:

     

printf'foo \ nbar \ n'| grep -z -q'foo [[:space:]] + bar'

     

如果这还不够,您可以在输入之前进行转换   转到“ grep”或转到“ awk”,“ sed”,“ perl”或许多其他实用程序   旨在跨线运行。