【问题标题】:Negative lookbehind problem负后视问题
【发布时间】:2011-05-23 00:00:08
【问题描述】:

这里是示例文本(从原文简化):

<start1>
<name="4654">
bla bla bla bla
<tags="bla" model="c">
bla bla bla bla
<start2>
<name="12346">
bla bla bla bla
<tags="bla" model="d">
bla bla bla bla
<start3>
<name="73535">
bla bla bla bla
<tags="bla" model="c">
<start4>
<name="546875">
bla bla bla bla
<tags="bla" model="c">
bla bla bla bla

这是我的正则表达式(点匹配换行选项已打开)

name="([\d]+)".+?(?<!start)tags="([^"]+?)" model="c"

如您所见,有 4 个块,但我需要将它们与 model="c" 匹配。但是.+? 捕获的内容超出了它的需要。将负面的向后看以抑制它不起作用......知道如何排除块吗?

更新(澄清我想要实现的目标):

样本数据中我想匹配以下 3 个块:

第一场比赛

<name="4654">
bla bla bla bla
<tags="bla" model="c">

第二场比赛

<name="73535">
bla bla bla bla
<tags="bla" model="c">

第三场比赛

<name="546875">
bla bla bla bla
<tags="bla" model="c">

【问题讨论】:

  • 如果是XML,最好使用XPath。
  • 这看起来不像 XML。这是更糟糕的事情。 :)
  • 不是。我刚刚使用 xml 元素来简化示例数据。
  • 你能解释一下正则表达式应该做什么吗?应该捕获多少?查看非功能性正则表达式并不能让我们了解您希望实现的目标。
  • @Mike Pennington:当然,更新了。谢谢!

标签: python regex


【解决方案1】:

是否总是采用这种格式(startnametags)、(startnametags)等等?如果是这样,您甚至可以不用环视。

/<name="(\d+)"[^<]+?<tags="([^"]+?)" model="c">/s

这很有效,因为您知道您遇到的下一个&lt; 将是紧随其后的tags 标签。我们可以保证是这种情况,还是我们需要更笼统以允许混合使用其他标签?

另外,您是否需要在&lt;tags&gt; 之后和下一个&lt;start&gt; 之前捕获文本?如果是这样,您可以为此添加一些额外的内容。

/<name="(\d+)"[^<]+?<tags="([^"]+?)" model="c">[^<]*(?!<start)/s

好的,根据您的 cmets,情况并非如此。那就从头开始吧。


更新

好的,那怎么样?

/<name="(\d+)"(?:(?!<start).)+<tags="([^"]+?)" model="c">/s

这实际上使用了前瞻,而不是后瞻。简单的前瞻/后瞻只会断言字符串出现在文本块之前或之后,而不是在文本块内。通过使用((?!str).)+ 检查每个字符,您可以有效地确保整个文本中不包含“str”。

我使用前瞻检查&lt;start 可能看起来令人困惑,而后向检查start 看起来像(?&lt;!start) 而不是(?!&lt;start)
想想(?!(&lt;start))(?&lt;!(start))

我添加了(?: ),这样它就不会被捕获。

【讨论】:

  • @Wiseguy:名称和标签之间的文字可能包含&lt;&gt;,应根据start关键字是否存在。不,我不需要捕获网络&lt;tags&gt;&lt;start&gt;
  • @Michael 查看更新。检查“
  • @Wiseguy:这确实是个把戏,现在如果你能详细说明一下,我将不胜感激:)
  • @Mike Pennington:我知道有办法 :)
  • @Wiseguy:这里的关键部分是捕获(非捕获)组,仍然不是很明显,但感谢您的解释和解决方案!
【解决方案2】:

尝试更改您的排除模式以使 model="c" 不贪婪,而不是消极的向后看。

name="([\d]+)".+?(?!model=)tags="([^"]+?)" model="c"

【讨论】:

  • 它仍然合并块&lt;start2&gt;&lt;start3&gt;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
  • 1970-01-01
  • 1970-01-01
  • 2013-01-31
  • 2011-09-08
  • 2019-01-15
相关资源
最近更新 更多