【问题标题】:Match pattern with exceptions匹配模式与异常
【发布时间】:2013-03-15 23:03:25
【问题描述】:

我想使用正则表达式匹配一个模式,但我需要一些例外来匹配。例如,匹配所有出现的“John Doe”,除了“John Doe”被粗体标签括起来的那些出现,即“<b>John Doe</b>”。

Match: John Doe
Don't match: <b>John Doe</b>

如何使用正则表达式实现这一点?

澄清:我想排除粗体标签之间的所有内容。此排除的内容可能包含多种字符、换行符等。

【问题讨论】:

  • 你的正则表达式风格是什么?这很重要,因为并非所有风格都提供诸如负后视之类的东西。
  • &lt;b&gt;&lt;i&gt;John Doe&lt;/i&gt;&lt;/b&gt; 用粗体标记括起来。要排除它吗?
  • 这是一个 PHP preg_replace 函数。在我的示例中,我想排除两个粗体标签之间的所有内容。粗体标签中的内容将具有不同的种类,并且将包含来自不同语言的代码。我会尝试这里提供的一些建议。谢谢!
  • @nhahtdh 如果我们开始尝试排除 &lt;b&gt;some trap&lt;/b&gt;John Doe&lt;b&gt;some trap&lt;/b&gt;,我们可能会以 pon̷ies 结束...
  • 根据您的说明:您想匹配不在粗体标签之间的任何内容吗?即从&lt;b&gt; 到(第一次出现)&lt;/b&gt; 的任何内容都应该匹配吗?

标签: regex


【解决方案1】:

如果您的正则表达式方言允许环视,您可以使用否定的lookbehind 和否定的lookahead 来完成该任务:

(?<!<b>)John Doe(?!<b>)

【讨论】:

  • 谢谢!我会对此投赞成票,但将另一个答案标记为正确只是因为它更详细一点。
【解决方案2】:

您可以为此使用消极的环顾四周:

(?<!<b>)John Doe(?!</b>)

这也不匹配 &lt;b&gt;John DoeJohn Doe&lt;/b&gt;

如果您只想不匹配带有开始和结束标记的实例,您可以执行以下操作:

John Doe(?!(?<=<b>John Doe)</b>)

或者稍微短一些(但不太容易理解 - 8 是 John Doe 的长度):

 John Doe(?!(?<=<b>.{8})</b>)

【讨论】:

  • 谢谢!这几乎就是我想要的。虽然,John Doe 必须允许在其前后有换行符和其他字符。我只知道在粗体标签之间的某处,出现了John Doe,它一定不能被模式匹配。
  • 在封闭的粗体标签内是否有粗体标签?要么其中之一,要么两者兼而有之。或者你知道你永远不会在封闭的粗体标签中找到&lt;b&gt;&lt;/b&gt;?另外:“封闭”粗体标签是整个字符串中的only粗体标签吗?
  • 我知道我永远不会在粗体标签中使用粗体标签。不,整个字符串中会有几对粗体标签。
【解决方案3】:

使用 Perl,您可以使用否定的lookbehind:

$ echo "<b>John Doe</b>" | perl -ne 'print if /(?<!<b>)John Doe/'

(上面没有打印 - 不匹配)。

$ echo "John Doe" | perl -ne 'print if /(?<!<b>)John Doe/'
John Doe

(高于匹配项)。

符号(?&lt;!&lt;b&gt;) 是一个否定的lookbehind - 如果它后面没有跟它里面的内容(&lt;b&gt; 在这种情况下),则字符串匹配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 2019-06-01
    • 1970-01-01
    相关资源
    最近更新 更多