匹配以特殊字符开头或结尾的整个单词

时间:2018-09-06 22:27:11

标签: javascript regex

我需要JavaScript中的正则表达式来匹配以特殊字符开头或结尾的整个单词吗?

本来应该很容易,但是由于某种原因,\b之后的?并没有达到我的预期:

> /FOO\?/.exec('FOO? ')
[ 'FOO?', index: 0, input: 'FOO? ', groups: undefined ]
> /FOO\?\b/.exec('FOO? ')
null

我需要什么,例如,如果我的单词是“ FOO”? (包括问号),我要匹配:

“ FOO?很酷”,“您认为FOO吗?”

但不是:“ FOO很酷”,“ FOO?很酷”,“ aaFOO?很酷”

它也适用于以“?”开头的单词。例如,如果我的单词为“?FOO”,我想匹配:

“?FOO很酷”,“我爱?FOO”

但不是:“ FOO很酷”,“ FOO?很酷”,“ aaFOO?很酷”

我希望这是有道理的。

1 个答案:

答案 0 :(得分:1)

\b单词边界构造是错误的。您需要使用明确的结构,以确保匹配的单词的左/右有非单词字符或字符串的开始/结尾。

您可以使用

/(?:^|\W)\?FOO\?(?!\w)/g

在这里,(?:^|\W)是一个非捕获组,它与字符串的开头或任何非单词char,ASCII字母,数字和_以外的char匹配。 (?!\w)是一个否定的超前查询,如果在当前位置的右边立即有一个字符char,则匹配失败。

或者,在与ECMAScript 2018兼容的JS环境中,

/(?<!\w)\?FOO\?(?!\w)/g

请参见this regex demo

(?<!\w)是一个向后看的负数,如果当前位置的左侧紧跟着一个字符char,则匹配失败。

在代码中,您可以将其直接与String#match一起使用以提取所有出现的内容,例如s.match(/(?<!\w)\?FOO\?(?!\w)/g)

第一个表达式需要一个围绕您要提取的单词的捕获组:

var strs = ["?FOO is cool", "I love ?FOO", "FOO is cool", "FOO?is cool", "aaFOO?is cool"];
var rx = /(?:^|\W)(\?FOO)(?!\w)/g;
for (var s of strs) {
  var res = [], m;
  while (m=rx.exec(s)) {
    res.push(m[1]);
  }
  console.log(s, "=>", res);
}