捕获不属于 link 的特定单词的所有出现

Capturing all the occurrences of a specific word when is not part of a link

我正在尝试使用正则表达式从 HTML 文本中使用 PCRE2 方言获取单词 'apple' 的所有出现。但不包括 apple 这个词是 link.
的一部分 我是 Regex 的初学者,可能我犯了一个很简单的错误。

\bapple\b

因此,以下文本必须匹配第一次出现但不匹配第二次和第三次。

Lorem ipsum apple sit amet, consectetur <a href="#">apple</a> elit <a href="/test/apple">lorem</a>. 

我做错了什么?

我更改了您的正则表达式以查找锚点并避免 select 那一行。

/^(?!.*(\<a.*?\>)).*$/ism

https://regex101.com/r/kE4mJ0/1

评论升级为回答:

match me(?!.*?\<\/a\>) 

https://regex101.com/r/hH3rL1/1

匹配 HTML 使用正则表达式非常棘手。此处接受的答案不允许匹配位于两个单独锚标记之间的字符串,例如:

HTML:

<a href="#">Don't Match Me <span>web</span></a>
match me
<a href="#">Don't Match Me</a>match me<a href="#">Don't Match Me</a>

我之前为此使用过以下正则表达式,但这只适用于 php: https://regex101.com/r/v0FfFC/1

<a[^>]*>(?:[a-zA-Z0-9\s'\-\.,]|(?:<(.*)>.*<\/>))*<\/a>(*SKIP)(*FAIL)|\b(match me)\b(?=[^>]*(?:<|$))

在 PCRE 中,您可以使用此正则表达式:

~(?is)<a .*?</a>(*SKIP)(*F)|\bapple\b~

RegEx Demo

正则表达式详细信息:

  • (?is):启用忽略大小写和 DOTALL 模式
  • <a .*?</a>:匹配从 <a</a> 的文本以跳过所有 <a> 阶段
  • (*SKIP)(*F):一起提供了一个很好的限制替代方案,你不能在 PCRE 正则表达式中有可变长度的回顾
  • |: 或
  • \bapple\b:匹配词apple

由于 PHP 正则表达式是基于 PCRE2 的,您可以使用 (*SKIP)(*F)/(*SKIP)(*FAIL) regex:

/<a(?:\s[^>]*)?>.*?<\/a>(*SKIP)(*F)|\bMatch Me\b/is

参见regex demo

详情

  • <a - <a<A(因为使用了 i 标志,模式不区分大小写)
  • (?:\s[^>]*)? - 可选出现空白字符 (\s),然后是 > 以外的任何零个或多个字符(参见 [^>]*)(这部分确保我们匹配 <a> 以及 <a attr=value attr2=value2...> 种标签)
  • > - 一个 > 字符
  • .*? - 任何零个或多个字符,尽可能少(s 标志也使 . 匹配换行字符)
  • <\/a> - </a></A>
  • (*SKIP)(*F) - 跳过匹配,从失败发生的位置继续寻找更多的匹配
  • | - 或
  • \bMatch Me\b - 整个单词 Match me(不包含字母、数字或 _ 个字符)。