Regex-查找所有不匹配的单词';不要以特定的前缀开头

Regex-查找所有不匹配的单词';不要以特定的前缀开头,regex,Regex,如何构造正则表达式来查找以字符串结尾但不以字符串开头的所有单词 e、 g.在下面的句子中找出所有以“friend”结尾的单词,而不是以“girl”开头的单词: “当一个男朋友和女朋友要求与他们成为朋友时,他们得到了一个朋友” 粗体显示的项目应匹配。“女朋友”这个词不应该出现。试试这个: /\b(?!girl)\w*friend\b/ig 这可能会起作用: \w*( 你也可以试试 \w*(?如果你想匹配像成为朋友或男朋友这样的词 我不确定?是否在所有的正则表达式版本中都可用,但这个表达式在Exp

如何构造正则表达式来查找以字符串结尾但不以字符串开头的所有单词

e、 g.在下面的句子中找出所有以“friend”结尾的单词,而不是以“girl”开头的单词:

“当一个男朋友和女朋友要求与他们成为朋友时,他们得到了一个朋友”

粗体显示的项目应匹配。“女朋友”这个词不应该出现。

试试这个:

/\b(?!girl)\w*friend\b/ig
这可能会起作用:

\w*(

你也可以试试

\w*(?如果你想匹配像
成为朋友
男朋友
这样的词


我不确定
?是否在所有的正则表达式版本中都可用,但这个表达式在Expersso(我相信是.NET)中起作用。

在我的脑海中,您可以尝试:

\b             # word boundary - matches start of word
(?!girl)       # negative lookahead for literal 'girl'
\w*            # zero or more letters, numbers, or underscores
friend         # literal 'friend'
\b             # word boundary - matches end of word
更新

下面是另一种不明显的方法,它应该适用于正则表达式的任何现代实现:

假设您希望提取一个出现在多个上下文中的模式,但您只想在它出现在特定上下文中时进行匹配,那么您可以使用一个更改,首先指定您不想要的,然后捕获您要做的

因此,以您的示例为例,要提取除
女朋友
之外的所有以
朋友
结尾的单词,您可以使用:

\b               # word boundary
(?:              # start of non-capture group 
  girlfriend     # literal (note 1)
|                # alternation
  (              # start of capture group #1 (note 2)
    \w*          # zero or more word chars [a-zA-Z_]
    friend       # literal 
  )              # end of capture group #1
)                # end of non-capture group
\b
注:

  • 这是我们不需要捕获的内容
  • 这就是我们要捕捉的
  • 可以描述为:

    • 不言而喻
    • 首先,匹配“女朋友”,不要捕获(丢弃)
    • 然后匹配任何以“friend”结尾的单词并捕获它
    在Javascript中:

    const target = 'A boyfriend and girlfriend gained a friend when they asked to befriend them';
    
    const pattern = /\b(?:girlfriend|(\w*friend))\b/g;
    
    let result = [];
    let arr;
    
    while((arr=pattern.exec(target)) !== null){
      if(arr[1]) {
        result.push(arr[1]);
      }
    }
    
    console.log(result);
    
    运行时,将打印:

    [ 'boyfriend', 'friend', 'befriend' ]
    

    我将Rob Raisch的答案更改为一个regexp,它可以查找包含特定子字符串的单词,但不包含其他特定子字符串

    \b(?![\w_]*Unwanted[\w_]*)[\w_]*Desired[\w_]*\b
    
    因此,例如,(![\w\u]*mon[\w\u]*)[\w\u]*day[\w\u]*\b会发现每个单词中都有“day”(如day,周二,daywalker),除非它还包含“mon”(如周一)


    可能对某些人有用。

    对于正则表达式问题,提及您使用的语言是很有帮助的,因为对于同一任务,正则表达式的语法可能会有所不同。请注意,虽然许多正则表达式不支持“向后看”,但大多数都支持“向前看”。我给出的答案将在JavaScript中使用,JavaScript不支持rt look-behind.虽然不是最快的答案,+1作为解释!不过有点吹毛求疵:
    \b
    更适合称为“单词边界”。@BartKiers,没错,但在这种情况下,它的目的是界定单词的开头和结尾。当然,我知道。但事实上,你第一次称它为“开始”,第二次称它为“结束”可能会让人相信它们在不同的地方匹配不同的东西。此外,“边界”在这里是(IMO)更好的词,因为很明显它是一个“零宽度”模式(它不匹配任何字符,只匹配一个位置)。但是,就像我说的:一个小小的挑剔。我在regex101中自由地创建了一个始终匹配的示例“friend”(第1组中的一个空字符串)@Bart Kiers:它总是在哪里匹配?当我用Expresso进行测试时,它与“friend”不匹配。正确,它与前面的“girl”一词不匹配。我的意思是,在“男友”一词的情况下,只有“friend”一词“是匹配的。这是它将始终匹配的:只有“朋友”一词。OP声明:“粗体项目应该匹配。”其中包括“男朋友”、“朋友”和“朋友”(“男孩”和“被”包括在内).但是,我认为没有真正的理由调整你的答案,因为正确的答案已经发布了不止一次。它似乎不适用于非字母数字字符。例如,如果我想检索所有的点,“.”除了以“@”开头的单词(例如:Hello.@some.thing不起作用。-->应该在“Hello”之后检测点”在句末,但不是在“@some.thing”中。