Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

javascript - Matching whole words that start or end with special characters

I need a regular expression in javascript that matches whole words that start or end with special characters?

It was supposed to be easy, but for some reason after ? doesn't behave as I expected:

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

What I need, for instance if my word is "FOO?" (including the question mark), I want to match:

"FOO? is cool", "do you think that FOO??"

but not: "FOO is cool", "FOO?is cool", "aaFOO?is cool"

It should also work for words that start with "?". For instance, if my word if "?FOO", I want to match:

"?FOO is cool", "I love ?FOO"

but not: "FOO is cool", "FOO?is cool", "aaFOO?is cool"

I hope it makes sense.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The word boundary construct is ambiguous. You need to use unambiguous constructs that will make sure there are non-word chars or start/end of string to the left/right of the word matched.

You may use

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

Here, (?:^|W) is a non-capturing group that matches either the start of a string or any non-word char, a char other than an ASCII letter, digit and _. (?!w) is a negative lookahead that fails the match if, immediately to the right of the current location, there is a word char.

Or, with ECMAScript 2018 compatible JS environments,

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

See this regex demo.

The (?<!w) is a negative lookbehind that fails the match if there is a word char immediately to the left of the current location.

In code, you may use it directly with String#match to extract all occurrences, like s.match(/(?<!w)?FOO?(?!w)/g).

The first expression needs a capturing group around the word you need to extract:

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);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...