JavaScript 正则表达式 select 仅最后一次出现

JavaScript regexp select only last occurrence

Select 仅最后一次出现

我正在尝试 select 最后一个词(直到 space),这些是在最后一个 white space@ 字符之后。

以下是我的字符串

hello hi @why helo @blow but @name             // capture: name
hello hi @why helo @blow but name@name         // capture: blow

和另一个字符串

@blow but not know how to resolve this         // capture: blow

这里最后出现的是第一个词blow,select仅在第一个词后@个词(显然白色space不在第一个词中)。

我试过这个:https://regex101.com/r/pG1kU1/1

您可以简单地使用否定前瞻:

@[^@]\w*(?!.*@[^@]\w*)

regex101 demo.

(?:) 意味着它里面的正则表达式不能在那个点之后出现。所以这个正则表达式表明在匹配的项目之后,你不能在它旁边找到另一个@-thing。这意味着它显然是最后一个 @-东西。

注意案例:

@blow but not know how to resolve this@
^                                     ^
|                                     |
will match this one                   |
        because this is not a valid @/

@blow 被选中,因为 @ - 根据您的正则表达式需要至少一个字符。如果要匹配@部分,需要修改为:

@[^@]?\w*(?!.*@[^@]?\w*)

或更高效

@[^@]?\w*(?!.*@)

如果 @ 前面必须有字符串的开头或空格,您可以使用单词边界 \B:

\B@[^@]?\w*(?!.*\B@[^@]?\w*)

regex101 demo

/(?:^|\s)(@[^@]\w*)(?!.*\s@)/

应该可以;你的话将是第一次捕获。在支持 lookbehinds 的语言中,你可以做

/(?<=^|\s)@[^@]\w*(?!.*\s@)/

并让整个捕获成为您想要的;然而,这在 JavaScript.

中是不可能的

如果您只满足于分词而不是 space,这也适用:

/\b@[^@]\w*(?!.*\s@)/

我们的想法是通过积极的前瞻性检查我们的比赛之后没有进一步的 @word

(?:^| )@([^@\s]+)(?!.*?\s@\w+.*$)

您可以尝试 this.See 演示。

https://regex101.com/r/pG1kU1/3

最简单的答案:

/\B@[^@]\w*(?!.*?\s@)/

DEMO

作为替代方案,这样的事情怎么样?

var strings = [
    'hello hi @why helo @blow but @name',
    'hello hi @why helo @blow but name@name',
    '  hello   hi   @why   helo    @blow    but    name@name  ',
    '@blow but not know how to resolve this',
    '  @blow   but   not   know   how   to   resolve   this',
    'tada',
    '    ',
    ''
];

var wanted = strings.map(function (element) {
    var found = 'not found';
    
    element.split(/\s+/).reverse().some(function (part) {
        if (part.charAt(0) === '@') {
            found = part.slice(1);
            
            return true;
        }
    });
    
    return found;
});

document.getElementById('out').textContent = wanted.join('\n')
<pre id='out'></pre>

没有复杂的 RegExp,易于理解和更改行为。确实需要 ES5 或垫片,但没什么大不了的。