JavaScript 正则表达式全局匹配组
Posted
技术标签:
【中文标题】JavaScript 正则表达式全局匹配组【英文标题】:JavaScript Regex Global Match Groups 【发布时间】:2013-11-23 16:28:30 【问题描述】:更新:这个问题与this几乎重复
我确定我的问题的答案就在那里,但我找不到简洁的词语来表达它。我正在尝试使用 javascript 正则表达式执行以下操作:
var input = "'Warehouse','Local Release','Local Release DA'";
var regex = /'(.*?)'/g;
console.log(input.match(regex));
// Actual:
// ["'Warehouse'", "'Local Release'", "'Local Release DA'"]
// What I'm looking for (without the '):
// ["Warehouse", "Local Release", "Local Release DA"]
有没有一种干净的方法来使用 JavaScript 正则表达式来做到这一点?显然我可以自己去掉'
s,但我正在寻找正确的方法来使用正则表达式捕获全局匹配的分组。
【问题讨论】:
How do you access the matched groups in a javascript regex?的可能重复 是的,这绝对是重复的,我不知道如何搜索我的问题:/ 我是通过搜索[javascript] [regex] 全局捕获组找到的。 【参考方案1】:要使用正则表达式执行此操作,您需要使用 .exec()
对其进行迭代,以获得多个匹配的组。带有 match 的 g
标志只会返回多个完整的匹配,而不是您想要的多个子匹配。这是使用.exec()
的一种方法。
var input = "'Warehouse','Local Release','Local Release DA'";
var regex = /'(.*?)'/g;
var matches, output = [];
while (matches = regex.exec(input))
output.push(matches[1]);
// result is in output here
工作演示:http://jsfiddle.net/jfriend00/VSczR/
对字符串中的内容进行某些假设后,您也可以直接使用:
var input = "'Warehouse','Local Release','Local Release DA'";
var output = input.replace(/^'|'$/, "").split("','");
工作演示:http://jsfiddle.net/jfriend00/MFNm3/
注意:使用截至 2021 年的现代 Javascript 引擎,您可以使用 str.matchAll(regex)
并在一个函数调用中获取所有匹配项。
【讨论】:
添加了一个非正则表达式的方式也可以做到这一点。 我用这个正则表达式/<img[^>]+?src=(?:(?:'([^']*)')|(?:"([^"]*)")|([^\s]*))/i
应用了这个循环,控制台不响应并且使用 1 个完整的 cpu 核心进行 chrome 处理
哦,我忘记了g
修饰符。现在好了
这将在 jslink 中失败.. 改为这样做 while ((matches = regex.exec(input)) !== null)
@keithics - jslink 返回的不是null
到底是什么?这很奇怪。 .exec()
应该返回一个数组或 null
所以原始代码应该检测到不匹配就好了。【参考方案2】:
有一个名为 String.prototype.matchAll()
的 ECMAScript 提案可以满足您的需求。
【讨论】:
看来这已经得到很好的支持了!甜! 没错:caniuse.com/?search=String.prototype.matchAll【参考方案3】:不是很通用的解决方案,因为 Javascript 不支持lookbehind,但是对于给定的输入,这个正则表达式应该可以工作:
m = input.match(/([^',]+)(?=')/g);
//=> ["Warehouse", "Local Release", "Local Release DA"]
【讨论】:
【参考方案4】:String.prototype.matchAll
现在是 well supported in modern browsers 以及 Node.js. 这可以这样使用:
const matches = Array.from(myString.matchAll(/myRegEx/g)).map(match => match[1]);
注意传递的RegExp
必须有全局标志,否则会抛出错误。
方便的是,当找不到匹配项时,这不会引发错误,因为 .matchAll
总是返回一个迭代器(而不是 .match()
返回 null
)。
对于这个具体的例子:
var input = "'Warehouse','Local Release','Local Release DA'";
var regex = /'(.*?)'/g;
var matches = Array.from(input.matchAll(regex)).map(match => match[1]);
// [ "Warehouse", "Local Release", "Local Release DA" ]
【讨论】:
Array.from
接受 mapFn
作为第二个参数。所以还有可能是:Array.from(myString.matchAll(/myRegEx/g), m => m[1])
。 MDN 在其 matchAll
文档中使用它作为示例,请参阅 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…【参考方案5】:
尝试input.replace(regex, "$1")
之类的方法来获取捕获组的结果。
【讨论】:
进入数组 -input.replace(regex, "$1").split(',')
OP 想要数组中的结果。
我喜欢你的思路,假设内容中没有,
s。
@Jondlm 可以做 - regex = /'(.*?)'(,?)/g;
和 input.replace(regex, "$1$2$2").split(',,')
【参考方案6】:
使用 es2020 你可以使用matchAll
:
var input = "'Warehouse','Local Release','Local Release DA'";
var regex = /'(.*?)'/g;
const match_all = [...input.matchAll(regex)];
如果您使用的是打字稿,请不要忘记将其设置在tsconfig.json
:
"compilerOptions":
"lib": ["es2020.string"]
【讨论】:
【参考方案7】:此正则表达式有效,但使用已定义的字符...
var input = "'Warehouse','Local Release','Local Release DA'";
var r =/'[\w\s]+'/gi;
console.log(input.match(regex));
【讨论】:
这会在结果中留下单引号,这不是 OP 想要的。【参考方案8】:编辑:这在 javascript 中不起作用,但它在 java 中起作用。对不起。
是的,它被称为“向前看”和“向后看”
(?<=').*?(?=')
(?=') 向前寻找 '
(?
测试一下here
【讨论】:
在javascript中没有后面的样子。 既然知道它在 Javascript 中不起作用,为什么还要写它呢?否则人们会用 Java 标签询问。乞丐的信仰…… JavaScript 中现在有look behind 这是一篇关于如何使用lookbehind和lookahed的文章:v8.dev/blog/regexp-lookbehind-assertions以上是关于JavaScript 正则表达式全局匹配组的主要内容,如果未能解决你的问题,请参考以下文章