我想将/(a).(b)(c.)d/
这样的正则表达式与"aabccde"
进行匹配,并返回以下信息:
"a" at index = 0
"b" at index = 2
"cc" at index = 3
String.match返回匹配列表和完整匹配的开始索引,而不是每个捕获的索引。
编辑:一个不能使用普通indexOf的测试用例
regex: /(a).(.)/
string: "aaa"
expected result: "a" at 0, "a" at 2
注意:这个问题类似于Javascript Regex: How to find index of each subexpression?,但我不能修改正则表达式使每个子表达式都成为捕获组。
8条答案
按热度按时间khbbv19g1#
目前有一个proposal(阶段4)在原生Javascript中实现这一点:
ECMAScript的RegExp匹配索引
ECMAScript RegExp匹配索引提供了有关捕获的子字符串相对于输入字符串开始的开始和结束索引的附加信息。
...我们建议在数组结果上采用额外的
indices
属性(substrings array)。该属性本身是一个索引数组,包含每个捕获的子串的一对开始和结束索引。任何 unmatched 捕获组将是undefined
,类似于它们在 *substrings数组 * 中的对应元素。此外,*indices数组 * 本身将具有包含每个命名的捕获组的开始和结束索引的groups属性。下面是一个例子,说明了事情是如何工作的。以下代码段至少在Chrome中运行时没有错误:
因此,对于问题中的代码,我们可以这样做:
输出:
请记住,
indices
数组包含匹配组的索引 * 相对于字符串的开始 *,而不是相对于匹配的开始。polyfill可用于here。
wgmfuz8q2#
我不久前为此写了MultiRegExp。只要你没有嵌套的捕获组,它应该可以做到这一点。它的工作原理是在RegExp中的捕获组之间插入捕获组,并使用所有中间组来计算请求的组位置。
应返回
Live Version
uqxowvwt3#
我创建了一个小的正则表达式解析器,它也能够像魔咒一样解析嵌套的组。它很小,但很大。真的。就像Donalds的手一样。如果有人能测试它,我会很高兴,所以它会经过战斗测试。它可以在以下位置找到:https://github.com/valorize/MultiRegExp2
使用方法:
eoxn13cs4#
更新答案:2022年
参见String.prototype.matchAll
matchAll()
方法将字符串与正则表达式进行匹配,并返回iterator
个匹配结果。每个匹配项都是一个数组,匹配的文本作为第一项,然后每个括号捕获组都有一项。它还包括额外的属性
index
和input
。k2fxgqgv5#
所以,你有一个文本和一个正则表达式:
第一步是获取匹配正则表达式的所有子字符串的列表:
然后,你可以对每个子字符串的文本做一个简单的搜索。你必须在一个变量中保存最后一个子字符串的位置。我把这个变量命名为
cursor
。**编辑:**感谢@nhahtdh,我改进了机制,做了一个完整的函数:
i86rm4rw6#
基于ecma正则表达式语法,我编写了一个解析器,它是RegExp类的扩展,除了解决这个问题(全索引exec方法)之外,还解决了JavaScript RegExp实现的其他限制,例如:基于组的搜索和替换。您可以test and download the implementation here(与NPM模块一样可用)。
该实现的工作原理如下(小示例):
我也尝试了@velop的实现,但该实现似乎有缺陷,例如它不能正确处理反向引用,例如“/a(?:)bc(def(\1ghi)xyz)/g”-当在前面添加括号时,则后向引用**\1**需要相应地递增(在他的实现中不是这种情况)。
4bbkushb7#
从2023年开始,你可以使用
match()
和这里提到的d
标志来实现这一点。所以要解决原始示例,你只需在正则表达式的末尾添加一个d
:Fiddle here
注意,第一个数组是 * 整个 * 匹配的开始和结束。子组在其后。
我将命名这些组,然后在
groups
属性(match.indices.groups
)下按名称访问它们的索引。8hhllhi28#
我不太清楚您对搜索的具体要求是什么,但下面是如何在第一个示例中使用
Regex.exec()
和while循环获得所需输出的。脚本语言
产出
使用
lastIndex
属性,可以减去当前匹配字符串的长度,以获得起始索引。