JavaScript regexp重复(子)组
是否可以使用正则表达式从单个调用返回所有重复和匹配的子组 例如,我有一个字符串,如:JavaScript regexp重复(子)组,javascript,regex,Javascript,Regex,是否可以使用正则表达式从单个调用返回所有重复和匹配的子组 例如,我有一个字符串,如: {{token id=foo1 class=foo2 attr1=foo3}} 其中属性的数量(即id,class,attr1)未定义,可以是任何key=value对 例如,在运动会上,我有以下几点 它似乎只与最后一组匹配;是否有任何方法可以获取所有其他“属性”(arg和id) 注意:该示例演示了单个字符串上的匹配,但搜索的模式可能位于更大的字符串中,可能包含许多匹配项。因此,^和$不能使用。您可以这样做:
{{token id=foo1 class=foo2 attr1=foo3}}
其中属性的数量(即id
,class
,attr1
)未定义,可以是任何key=value
对
例如,在运动会上,我有以下几点
它似乎只与最后一组匹配;是否有任何方法可以获取所有其他“属性”(arg
和id
)
注意:该示例演示了单个字符串上的匹配,但搜索的模式可能位于更大的字符串中,可能包含许多匹配项。因此,^
和$
不能使用。您可以这样做:
var s = "{{token id=foo1 class=foo2 attr1=foo3 hi=we}} hiwe=wef";
var matches = s.match(/(\w+(?==\w+)|(?!==\w+)\w+)(?!\{\{)(?!.*token)(?=.*}})/g);
matches.splice(0,1);
for (var i = 0; i < matches.length; i++) {
alert(matches[i]);
}
实时演示:这在一个正则表达式中是不可能做到的。JavaScript正则表达式将只返回最后一个匹配的组,这正是您的问题所在。我有一段时间前似乎有这个问题:。您可以在.Net中使用它,但这可能不是您所需要的 我相信您可以在正则表达式中找到如何实现这一点,并从第二组中提取参数
\{\{(\w+)\s+(.*?)\}\}
下面是一些javaScript代码,向您展示了它是如何完成的:
var input = $('#input').text();
var regex = /\{\{(\w+)\s*(.*?)\}\}/g;
var match;
var attribs;
var kvp;
var output = '';
while ((match = regex.exec(input)) != null) {
output += match[1] += ': <br/>';
if (match.length > 2) {
attribs = match[2].split(/\s+/g);
for (var i = 0; i < attribs.length; i++) {
kvp = attribs[i].split(/\s*=\s*/);
output += ' - ' + kvp[0] + ' = ' + kvp[1] + '<br/>';
}
}
}
$('#output').html(output);
那么,您希望在单个正则表达式中同时包含键和值吗?请提供一些测试用例以及输出应该是什么,我希望所有这些都返回。我想我可以有小组。可能是匹配的子数组,或者其他。@AmitJoki,已经有了一个测试用例,不管预期的输出是什么,我希望regexp匹配并返回(可能是子组)所有“属性”,而不仅仅是最后一个。这与您的问题无关,但我认为您的分组比您需要的多。看起来这个
“(?:[^”]*)”
可能就是这个“[^”]*”
太宽松了。它将包括{{}}
之外的匹配项,并且不检查标记
。仍然匹配}
之外的内容,并且您没有捕获OP想要的值。@cookiemonster,请参阅OP的命令是的,我看到了该注释。如问题所示,您只捕获了属性名,没有捕获值,也没有捕获起始标记(可能不是字面上的“标记”一词)。我真的不认为您理解他想要什么。这大概是为了某种模板系统,他需要每一组{{word attr=val attr2=val2}}
,其中一个大字符串中可能有多个分组,属性的值可能会被引用,也可能不会被引用。是的,我记得在某个时候在.Net中做过这件事,也许是我对子组和所有(.Net破坏了我的JavaScript!)感到困惑的原因。然后,我将匹配整个key=value
属性列表,并在这种情况下分别解析它们。只需稍加修改,就可以生成可以解析的JSON字符串。:)但是请注意,我决定放弃使用regexp,转而使用状态机解析器;更大的灵活性和错误管理。但是你提出了一个解决这个问题的创新方法。
\{\{(\w+)\s+(.*?)\}\}
var input = $('#input').text();
var regex = /\{\{(\w+)\s*(.*?)\}\}/g;
var match;
var attribs;
var kvp;
var output = '';
while ((match = regex.exec(input)) != null) {
output += match[1] += ': <br/>';
if (match.length > 2) {
attribs = match[2].split(/\s+/g);
for (var i = 0; i < attribs.length; i++) {
kvp = attribs[i].split(/\s*=\s*/);
output += ' - ' + kvp[0] + ' = ' + kvp[1] + '<br/>';
}
}
}
$('#output').html(output);
/[\s\S]*?(?:\{\{(\w+)\s+(.*?)\}\}|$)/g.replace(input, doReplace);
function doReplace ($1, $2, $3) {
if ($2) {
return "'" + $2 + "': {" +
$3.replace(/\s+/g, ',')
.replace(/=/g, ':')
.replace(/(\w+)(?=:)/g, "'$1'") + '};\n';
}
return '';
}