【问题标题】:Matching whole words that start or end with special characters匹配以特殊字符开头或结尾的整个单词
【发布时间】:2018-09-06 22:27:11
【问题描述】:

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

这应该很容易,但由于某种原因,\b? 之后的行为不像我预期的那样:

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

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

“FOO?很酷”,“你觉得FOO吗??”

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

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

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

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

我希望这是有道理的。

【问题讨论】:

  • 使用/FOO\?(?!\w)/
  • @WiktorStribiżew 你的建议的问题是它与 aaFOO? 不匹配
  • 所以,在前面加上一个单词边界,使用/\bFOO\?(?!\w)/或者/(?:^|\W)FOO\?(?!\w)/
  • @WiktorStribiżew 它有效。但如果我的词以? 开头,则它不起作用,例如?FOO

标签: javascript regex


【解决方案1】:

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

你可以使用

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

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

或者,使用兼容 ECMAScript 2018 的 JS 环境,

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

this regex demo

(?&lt;!\w) 是一个否定的lookbehind,如果当前位置的左侧有一个单词 char,则匹配失败。

在代码中,您可以直接将其与String#match 一起使用以提取所有出现的情况,例如s.match(/(?&lt;!\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);
}

【讨论】:

    最近更新 更多