RegEx:查找模式但排除单词

问题描述

我想找到除特定词之外的所有连接词。例如:

0827banana82/+wine22green-729

greenwine 应该匹配,但 banana 不匹配。

我尝试了以下带有否定前瞻的正则表达式:

(?!banana)([a-zA-Z]+)

但它只排除了 banana 的第一个字母,因为 anana 仍然是第二个模式的匹配项。我不知道如何摆脱它。

解决方法

您可以在正则表达式中添加负向后视以使其工作:

(?!banana)(?<![a-zA-Z])[a-zA-Z]+

RegEx Demo

正则表达式详情:

  • (?!banana):否定前瞻断言我们在当前位置之前没有字符串 banana
  • (?<![a-zA-Z]):否定后视断言我们在当前位置之前没有字母
  • [a-zA-Z]+:匹配 1 个以上的字母

PS:如果您想允许 bananas 之类的词,请使用:

(?!banana(?![a-zA-Z]))(?<![a-zA-Z])[a-zA-Z]+
,

你可以使用这个:

(banana)|([a-zA-Z]+)

哪个将在第一组中捕获香蕉,在第二组中捕获所有其他单词。

,

我的两分钱,假设您确实想要匹配诸如“bananas”之类的词:

(\b|\d)(?:banana|([a-zA-Z]+))(?1)

您的匹配项在第 2 组,请查看在线 demo

  • (\b|\d) - 保存字边界或数字的第一个捕获组。
  • (?:banana|([a-zA-Z]+)) - 一个非捕获组,交替使用“香蕉” 1+ alpha 字符的第二个捕获组。
  • (?1) - 重复第一个捕获组的子模式。

编辑:如果不支持反向引用,您可以尝试

(?:\b|\d)(?:banana|([a-zA-Z]+))(?:\b|\d)

或者,使用环视:

(?i)(?<![a-z])(?:banana|([a-z]+))(?![a-z])
,

另一种变体可能是匹配字符 a-zA-Z,直到不再匹配。然后断言香蕉不是直接在左边。

[a-zA-Z]+(?![a-zA-Z])(?<!banana)

模式匹配

  • [a-zA-Z]+ 匹配 1+ 个字符 a-zA-Z
  • (?![a-zA-Z]) 否定前瞻,断言不是直接向右 a-zA-Z
  • (?<!banana) 否定后视,断言 banana 不直接向左

Regex demo


如果你想匹配 bananasstraigtbanana,你可以断言左边不是以 a-zA-Z 开头的香蕉

[a-zA-Z]+(?![a-zA-Z])(?<!(?<![a-zA-Z])banana)

Regex demo


正如@bobble bubble 在评论中所建议的,如果支持 possessive quantifiers 并使用不区分大小写的匹配来缩短模式:

[a-z]++(?<!(?<![a-z])banana)
  • [a-z]++ 匹配 a-z 范围内的 1+ 个字符(所有格,不回溯)
  • (?<! 负向后视,断言直接在左边的不是
    • (?<![a-z])banana 否定后视,匹配之前没有 a-z 的香蕉
  • ) 近距离观察

Regex demo

,

使用下面的正则表达式来避免一个单词。

X.reset_index().assign(bayers_p=bayers_p['Column'].reset_index())
,
/\b(((?!banana|apple|[^\p{L}]).)+)\b/gu

您需要使用词边界 \b 表达式 \b。香蕉苹果将被排除在您的比赛之外。

最后,如果您还想排除 Banana 和 Apple(包括大写的大写文本),请使用 gui

\p{L} 将匹配任何单词,包括变音符号。

如果您只需要排除香蕉,请删除 |apple。如果您需要在苹果后添加更多类似橙色的元素,请添加 |orange