在 Javascript 中返回正则表达式 match() 的位置?
有没有办法检索 Javascript 中正则表达式 match() 结果字符串内的(起始)字符位置?
Is there a way to retrieve the (starting) character positions inside a string of the results of a regex match() in Javascript?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
exec
返回一个带有index
属性的对象:对于多个匹配:
exec
returns an object with aindex
property:And for multiple matches:
这是我想出的:
Here's what I came up with:
在现代浏览器中,您可以使用 字符串来完成此操作。 matchAll()。
与
RegExp.exec()
相比,这种方法的好处是它不依赖于有状态的正则表达式,如 @Gumbo 的回答。In modern browsers, you can accomplish this with string.matchAll().
The benefit to this approach vs
RegExp.exec()
is that it does not rely on the regex being stateful, as in @Gumbo's answer.来自 developer.mozilla.org 文档在 String
.match()
方法上:处理非全局正则表达式(即正则表达式上没有
g
标志)时,.match()
返回的值有一个index
财产...您所要做的就是访问它。这是一个显示它也有效的示例:
我已经成功地测试了这一点,一直到 IE5。
From developer.mozilla.org docs on the String
.match()
method:When dealing with a non-global regex (i.e., no
g
flag on your regex), the value returned by.match()
has anindex
property...all you have to do is access it.Here is an example showing it working as well:
I have successfully tested this all the way back to IE5.
您可以使用
String
对象的search
方法。这仅适用于第一场比赛,但否则会执行您所描述的操作。例如:You can use the
search
method of theString
object. This will only work for the first match, but will otherwise do what you describe. For example:这是我最近发现的一个很酷的功能,我在控制台上尝试了这个,它似乎有效:
返回:“border 6 Bottom 13 left 18 radius”
所以这似乎就是您正在寻找的。
Here is a cool feature I discovered recently, I tried this on the console and it seems to work:
Which returned: "border 6 bottom 13 left 18 radius"
So this seems to be what you are looking for.
如果您的正则表达式匹配宽度 0,恐怕之前的答案(基于
exec
)似乎不起作用。例如(注意:/\b/g
是应该找到所有单词边界的正则表达式):人们可以尝试通过让正则表达式匹配至少 1 个字符来解决此问题,但这远非理想(并且意味着您必须在字符串末尾手动添加索引)
更好的解决方案(仅适用于较新的浏览器/需要旧/IE版本的polyfills)是使用 String.prototype.matchAll()
说明:
String.prototype.matchAll() 需要一个全局正则表达式(设置了全局标志的
g
)。然后它返回一个迭代器。为了循环和map()
迭代器,必须将其转换为数组(这正是Array.from()
所做的)。与RegExp.prototype.exec()
的结果一样,根据规范,结果元素具有.index
字段。请参阅 String.prototype.matchAll()< /a> 和 Array.from() 浏览器支持和填充选项的 MDN 页面。
编辑:深入挖掘所有浏览器支持的解决方案
RegExp.prototype.exec()
的问题是它更新了lastIndex 指针指向正则表达式,下次从之前找到的
lastIndex
开始搜索。只要正则表达式匹配实际上有宽度,这种方法就很有效。如果使用 0 宽度的正则表达式,该指针不会增加,因此您会得到无限循环(注意:
/(?=l)/g
是 l 的前瞻——它匹配 0-l
之前的宽度字符串,因此它在第一次调用exec()
时正确地转到索引 2,然后停留在那里:因此,解决方案(不如 matchAll() 好,但应该适用于所有浏览器)是如果匹配宽度为 0(可以通过不同方式检查),则手动增加 lastIndex
I'm afraid the previous answers (based on
exec
) don't seem to work in case your regex matches width 0. For instance (Note:/\b/g
is the regex that should find all word boundaries) :One can try to fix this by having the regex match at least 1 character, but this is far from ideal (and means you have to manually add the index at the end of the string)
A better solution (which does only work on newer browsers / needs polyfills on older/IE versions) is to use String.prototype.matchAll()
Explanation:
String.prototype.matchAll() expects a global regex (one with
g
of global flag set). It then returns an iterator. In order to loop over andmap()
the iterator, it has to be turned into an array (which is exactly whatArray.from()
does). Like the result ofRegExp.prototype.exec()
, the resulting elements have an.index
field according to the specification.See the String.prototype.matchAll() and the Array.from() MDN pages for browser support and polyfill options.
Edit: digging a little deeper in search for a solution supported on all browsers
The problem with
RegExp.prototype.exec()
is that it updates thelastIndex
pointer on the regex, and next time starts searching from the previously foundlastIndex
.This works great as long as the regex match actually has a width. If using a 0 width regex, this pointer does not increase, and so you get your infinite loop (note:
/(?=l)/g
is a lookahead for l -- it matches the 0-width string before anl
. So it correctly goes to index 2 on the first call ofexec()
, and then stays there:The solution (that is less nice than matchAll(), but should work on all browsers) therefore is to manually increase the lastIndex if the match width is 0 (which may be checked in different ways)
我很幸运地使用了基于
matchAll
的单行解决方案(我的用例需要一个字符串位置数组)输出:[3, 9]
I had luck using this single-line solution based on
matchAll
(my use case needs an array of string positions)output: [3, 9]
该成员 fn 返回 String 对象内输入单词的从 0 开始的位置(如果有)的数组。
现在尝试
您还可以输入正则表达式:
这里获取线性项的位置索引。
This member fn returns an array of 0-based positions, if any, of the input word inside the String object
Now try
You can also input regular expressions:
Here one gets the position index of linear term.
或者
or