Grep 的行为不同于 Online RegEx-Tester

Grep behaves differently than Online RegExp-Tester

为了一个小的艺术项目,我需要从雅虎财经读取股票价格。 html-Source 相当复杂和冗长,但使用在线正则表达式测试器我想出了一个应该导致正确输出的正则表达式。

<span class\=\"Trsdu\(0\.3s\) Fw\(500\) Pstart\(10px\) Fz\(24px\)(\"| C\($dataGreen\)\"| C\($dataRed\)\") data-reactid\=\"35\">([-+]{0,1}\d*\.\d*) \((([-+]{0,1})\d*\.\d*)\%\)<\/span>

这里有一段代码,其中嵌套了结果:

<svg class="D(n) Cur(p)" width="24" style="fill:#000;stroke:#000;stroke-width:0;vertical-align:bottom;" height="24" viewBox="0 0 24 24" data-icon="search" data-reactid="29"><path d="M9 3C5.686 3 3 5.686 3 9c0 3.313 2.686 6 6 6s6-2.687 6-6c0-3.314-2.686-6-6-6m13.713 19.713c-.387.388-1.016.388-1.404 0l-7.404-7.404C12.55 16.364 10.85 17 9 17c-4.418 0-8-3.582-8-8 0-4.42 3.582-8 8-8s8 3.58 8 8c0 1.85-.634 3.55-1.69 4.905l7.403 7.404c.39.386.39 1.015 0 1.403" data-reactid="30"></path></svg></div></div></div><div class="My(6px) Pos(r) smartphone_Mt(6px)" data-reactid="31"><div class="D(ib) Va(m) Maw(65%) Ov(h)" data-reactid="32"><div class="D(ib) Mend(20px)" data-reactid="33"><span class="Trsdu(0.3s) Fw(b) Fz(36px) Mb(-4px) D(ib)" data-reactid="34">11,541.87</span><span class="Trsdu(0.3s) Fw(500) Pstart(10px) Fz(24px) C($dataRed)" data-reactid="35">-402.83 (-3.37%)</span><div id="quote-market-notice" class="C($tertiaryColor) D(b) Fz(12px) Fw(n) Mstart(0)--mobpsm Mt(6px)--mobpsm" data-reactid="36"><span data-reactid="37">At close:  5:44PM CET</span></div></div><!-- react-empty: 38 --></div></div></div></div></div><script>if (window.performance) {window.performance.mark && window.performance.mark('Lead-3-QuoteHeader');window.performance.measure && window.performance.measure('Lead-3-QuoteHeaderDone','PageStart','Lead-3-QuoteHeader');}</script></div><div data-reactid="29">

我的问题是:此正则表达式在在线测试器中的行为与在 openwrt 下的 egrep 中的行为不同!

在在线测试器中,结果正是这个片段:

<span class="Trsdu(0.3s) Fw(500) Pstart(10px) Fz(24px) C($dataGreen)" data-reactid="35">+50.32 (+0.17%)</span>

(由于正则表达式中的附加括号,标记了一些附加组)

如果我使用

egrep '<span class\=\"Trsdu\(0\.3s\) Fw\(500\) Pstart\(10px\) Fz\(24px\)(\"| C\($dataGreen\)\"| C\($dataRed\)\") data-reactid\=\"35\">([-+]{0,1}\d*\.\d*) \((([-+]{0,1})\d*\.\d*)\%\)<\/span>' stock.html

我绝对没有结果。 OK,一定是正则表达式有误。让我们从小事做起:

egrep '<span class' stock.html

给我很多结果。

egrep '<span class\=\"Trsdu\(0\.3s\) Fw\(500\)' stock.html

仍然会产生一些代码行。但是

egrep '<span class\=\"Trsdu\(0\.3s\) Fw\(500\) Pstart' stock.html

什么都没给我!晚安!纳达!甚至

egrep '<span class\=\"Trsdu\(0\.3s\) Fw\(500\) ' stock.html

(注意正则表达式末尾的空白 space!)没有给我任何结果。我不知道

之间有什么区别
egrep '<span class\=\"Trsdu\(0\.3s\) Fw\(500\)' stock.html

egrep '<span class\=\"Trsdu\(0\.3s\) Fw\(500\) Pstart' stock.html

是正则表达式方面的!如果空白 space 是问题所在,那么我应该已经在 "Fw" 之前的第一个空白 space 没有结果。那么,为什么我的正则表达式会因第二个空白而失败?

很可能Pstart前面那个空的space不是普通的space,而是一个表格。在使用 egrep 时,您还应该使用 POSIX 字符 类。试试这个:

egrep '<span[[:space:]]+class\=\"Trsdu\(0\.3s\)[[:space:]]+Fw\(500\)[[:space:]]+Pstart\(10px\)[[:space:]]Fz\(24px\)(\"|[[:space:]]+C\($dataGreen\)\"|[[:space:]]+C\($dataRed\)\")[[:space:]]+data-reactid\=\"35\">([-+]{0,1}[[:digit:]]*\.[[:digit:]]*)[[:space:]]\((([-+]{0,1})[[:digit:]]*\.[[:digit:]]*)\%\)<\/span>' stock.html