【问题标题】:RegEx HTML matching too much with lazy wildcardRegEx HTML 与惰性通配符匹配过多
【发布时间】:2014-03-11 02:12:53
【问题描述】:

正则表达式:

<span style='.+?'>TheTextToFind</span>

HTML:

<span style='font-size:11.0pt;'>DON'T_WANT_THIS_MATCHED <span style='font-size:18.0pt;'>TheTextToFind</span></span>

为什么匹配包含这个?

<span style='font-size:11.0pt;'>DON'T_WANT_THIS_MATCHED

Example Link

【问题讨论】:

标签: html regex vbscript regex-greedy non-greedy


【解决方案1】:

正则表达式引擎总是找到 left-most 匹配。这就是你得到的原因

<span style='font-size:11.0pt;'>DON'T_WANT_THIS_MATCHED <span style='font-size:18.0pt;'>TheTextToFind</span>

作为匹配。 (基本上是整个输入,没有最后一个&lt;/span&gt;)。

为了将引擎引导到正确的方向,如果我们假设 &gt; 没有直接出现在属性中,那么以下正则表达式将匹配您想要的。

<span style='[^>]+'>TheTextToFind</span>

此正则表达式匹配您想要的,因为根据上述假设,[^&gt;]+ 无法匹配标记之外。

但是,我希望您不要将其作为从 HTML 页面中提取信息的程序的一部分。为此目的使用 HTML 解析器。


要了解正则表达式匹配的原因,您需要了解.+? 会尝试回溯,以便找到与sequel ('&gt;TheTextToFind&lt;/span&gt;) 匹配的内容。

# Matching .+?
# Since +? is lazy, it matches . once (to fulfill the minimum repetition), and
# increase the number of repetition if the sequel fails to match
<span style='f                        # FAIL. Can't match closing '
<span style='fo                       # FAIL. Can't match closing '
...
<span style='font-size:11.0pt;        # PROCEED. But FAIL later, since can't match T in The
<span style='font-size:11.0pt;'       # FAIL. Can't match closing '
...
<span style='font-size:11.0pt;'>DON'  # PROCEED. But FAIL later, since can't match closing >
...
<span style='font-size:11.0pt;'>DON'T_WANT_THIS_MATCHED <span style='
                                      # PROCEED. But FAIL later, since can't match closing >
...
<span style='font-size:11.0pt;'>DON'T_WANT_THIS_MATCHED <span style='font-size:18.0pt;
                                      # PROCEED. MATCH FOUND.

如您所见,.+? 尝试增加长度并匹配 font-size:11.0pt;'&gt;DON'T_WANT_THIS_MATCHED &lt;span style='font-size:18.0pt;,这允许匹配 sequel '&gt;TheTextToFind&lt;/span&gt;

【讨论】:

  • 我仍然没有得到“最左边的匹配”。你能详细说明它是如何工作的吗?
  • @bradvido:从逻辑上讲,您可以认为引擎从索引 i 开始,然后它将穷举搜索从索引 i 开始与正则表达式匹配的所有子字符串(正则表达式将确定搜索顺序)。如果未找到匹配项,则它将尝试下一个索引 i+1。在这种情况下,由于它可以从索引 0 中找到正则表达式的匹配项,因此它将返回该匹配项。
猜你喜欢
  • 1970-01-01
  • 2022-06-11
  • 2011-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多