正则表达式:如何避免根据条件匹配字符串中的单词

Regex : How to avoid matching a word in a string upon a condition

我无法排除某些特殊情况。我已经在此 LINK.

中创建示例

如果我有这样的句子列表:

X-MAS TREE //it should be excluded because match my dictionary
BLA BLA TREE
XMAS TREE
X-MASTREE
X-TREE
X-MASTREE

而且我有词典 X-MAS TREE 有同义词:XMAS TREE, X-MASTREE, X-TREE, TREE。而且我需要把所有的近义词改成我的词典词。

如何排除圣诞树? 因为所有这些正则表达式都将替换为 X-MAS TREE 如果我用关键字 TREE 搜索,它将是无限循环,因为 X-MAS TREETREE

我已经尝试了很多组合,但都不起作用:

\b(XMAS TREE|X\-MASTREE|X\-TREE|TREE|(?!X\-MAS TREE)\b
\b(XMAS TREE|X\-MASTREE|X\-TREE|(?!X\-MAS \s)TREE)\b
\b(XMAS TREE|X\-MASTREE|X\-TREE|((?!X\-MAS )|\w*)TREE)\b
\b(XMAS TREE|X\-MASTREE|X\-TREE|(?:(?!X\-MAS) )TREE)\b

编辑

我需要使用边界(出于某种原因),因为我在我的代码中创建了带有循环的正则表达式,并且需要将它用于另一个字典,这就是为什么对于这种情况,我需要特殊条件(没有更改结构代码,仅编辑正则表达式 TREE)

你可以试试这个:

^(?!X-MAS\s+TREE\s*)(?=.*TREE).*$

Explanation

  1. ^ 断言行首的位置
  2. 负前瞻(?!X-MAS\s+TREE\s*)
  3. \s+ 匹配任何空白字符(等于 [\r\n\t\f\v ])
  4. 正向先行 (?=.*TREE) 断言下面的正则表达式匹配 .*
  5. $ 断言行尾的位置

为了掩盖你评论的结构,你可以试试消极的回头看

\b.*(?<!X-MAS )TREE\b

Tried here

如果你想匹配前面没有 X-MAS 的整个单词 TREE 和空格,你可以使用负向回顾 (?<!X-MAS\s)(或者,为了确保X-MAS是一个完整的词,(?<!\bX-MAS\s)):

String pat = "\b(?<!X-MAS\s)TREE\b";

参见regex demo

此外,如果可以有超过 1 个空格,比如从 1 到 10,您可以在 [=18= 之后添加一个 限制量词 {1,10} ] 以确保仍占 1 个以上的空格:

String pat = "\b(?<!X-MAS\s{1,10})TREE\b";

这里,即使X-MASTREE之间没有或最多有10个空格,否定条件(即所谓的constrained-width negative lookbehind)也会起作用。

参见 this Java demo