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不在第一个词中)。
您可以简单地使用否定前瞻:
@[^@]\w*(?!.*@[^@]\w*)
(?:)
意味着它里面的正则表达式不能在那个点之后出现。所以这个正则表达式表明在匹配的项目之后,你不能在它旁边找到另一个@-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*)
/(?:^|\s)(@[^@]\w*)(?!.*\s@)/
应该可以;你的话将是第一次捕获。在支持 lookbehinds 的语言中,你可以做
/(?<=^|\s)@[^@]\w*(?!.*\s@)/
并让整个捕获成为您想要的;然而,这在 JavaScript.
中是不可能的
如果您只满足于分词而不是 space,这也适用:
/\b@[^@]\w*(?!.*\s@)/
我们的想法是通过积极的前瞻性检查我们的比赛之后没有进一步的 @word
。
(?:^| )@([^@\s]+)(?!.*?\s@\w+.*$)
您可以尝试 this.See 演示。
最简单的答案:
/\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 或垫片,但没什么大不了的。
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不在第一个词中)。
您可以简单地使用否定前瞻:
@[^@]\w*(?!.*@[^@]\w*)
(?:)
意味着它里面的正则表达式不能在那个点之后出现。所以这个正则表达式表明在匹配的项目之后,你不能在它旁边找到另一个@-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*)
/(?:^|\s)(@[^@]\w*)(?!.*\s@)/
应该可以;你的话将是第一次捕获。在支持 lookbehinds 的语言中,你可以做
/(?<=^|\s)@[^@]\w*(?!.*\s@)/
并让整个捕获成为您想要的;然而,这在 JavaScript.
中是不可能的如果您只满足于分词而不是 space,这也适用:
/\b@[^@]\w*(?!.*\s@)/
我们的想法是通过积极的前瞻性检查我们的比赛之后没有进一步的 @word
。
(?:^| )@([^@\s]+)(?!.*?\s@\w+.*$)
您可以尝试 this.See 演示。
最简单的答案:
/\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 或垫片,但没什么大不了的。