我想使用正则表达式匹配字符串的一部分,然后访问带括号的子字符串:

var myString=“something format_abc”;//我要“abc”var arr=/(?:^|\s)format_(.*?)(?:\s|$)/.exec(myString);控制台日志(arr);//打印:[“format_abc”,“abc”]。。到现在为止,一直都还不错。控制台日志(arr[1]);//打印:未定义(???)控制台日志(arr[0]);//打印:format_undefined(!!!)

我做错了什么?


我发现上面的正则表达式代码没有任何问题:我测试的实际字符串是这样的:

"date format_%A"

报告“%A”未定义似乎是一种非常奇怪的行为,但它与这个问题没有直接关系,所以我打开了一个新的问题,为什么匹配的子字符串在JavaScript中返回“undefined”?。


问题是console.log像printf语句一样接受其参数,因为我记录的字符串(“%a”)有一个特殊值,所以它试图查找下一个参数的值。


当前回答

您的语法可能不是最好保留的。FF/Gekko将RegExp定义为Function的扩展。(FF2达到typeof(/patter/)==“函数”)

这似乎是FF特有的——IE、Opera和Chrome都有例外。

相反,使用其他人之前提到的方法:RegExp#exec或String#match。它们提供了相同的结果:

var regex = /(?:^|\s)format_(.*?)(?:\s|$)/;
var input = "something format_abc";

regex(input);        //=> [" format_abc", "abc"]
regex.exec(input);   //=> [" format_abc", "abc"]
input.match(regex);  //=> [" format_abc", "abc"]

其他回答

使用代码:

console.log(arr[1]);  // prints: abc
console.log(arr[0]);  // prints:  format_abc

编辑:Safari 3,如果重要的话。

字符串#matchAll(参见阶段3草案/2018年12月7日提案),简化了对匹配对象中所有组的访问(请记住,组0是整个匹配,而其他组对应于模式中的捕获组):

如果matchAll可用,则可以避免while循环并使用/g执行。。。相反,通过使用matchAll,您可以返回一个迭代器,您可以更方便地使用它。。。of、array spread或array.from()构造

此方法产生的输出类似于C#中的Regex.Matches,Python中的re.finditer,PHP中的preg_match_all。

查看JS演示(在Google Chrome 73.0.3683.67(官方版本),测试版(64位)中测试):

var myString=“key1:value1,key2-value2!!@key3=value3”;var matches=myString.matchAll(/(\w+)[:=-](\w*)/g);console.log([…matches]);//所有匹配捕获组值

console.log([…matches])显示

您还可以使用

let matchData=“key1:value1,key2-value2!!@key3=value3”.matchAll(/(\w+)[:=-](\w+)/g)var matches=[…matchData];//注意matchAll结果不可重复console.log(Array.from(matches,m=>m[0]));//所有匹配(组0)值//=>[“key1:value1”,“key2-value2”,“key 3=value3”]console.log(Array.from(matches,m=>m[1]));//所有匹配(组1)值//=>[“key1”,“key2”,“key 3”]

注意:请参阅浏览器兼容性详细信息。

我以为你只想抓取包含abc子字符串的所有单词并存储匹配的组/条目,所以我编写了这个脚本:

s='some format_abc另一个单词abc abc_somestring'console.log(s.match(/\b\w*abc\w*\b/igm));

\b-单词边界\w*-0+个字符abc-您的完全匹配\w*-0+个字符\b-单词边界

参考:Regex:匹配包含某个单词的所有单词https://javascript.info/regexp-introduction

只需使用RegExp$第1…$n组如:

1.匹配第一组RegExp$1.

匹配第二组RegExp$2.

如果在正则表达式中使用3组(请注意在string.match(正则表达式)之后使用)

注册Exp$1 RegExp$2 RegExp$3.

var str=“${印度}的雨很安全”;var res=str.match(/\${(.*?)\}/ig);//我在上面的例子中只使用了一个组,所以RegExp$1.console.log(RegExp.$1)

//最简单的方法是使用RegExp$1正则表达式中的第一组和第二组//注册Exp$如果存在,则在匹配后使用2var正则表达式=/\${(.*?)\}/ig;var str=“${SPAIN}的雨水主要停留在平原”;var res=str.match(正则表达式);for(res的常量匹配){var res=match.match(正则表达式);console.log(匹配);console.log(RegExp.$1)}

关于上面的多匹配括号示例,我在没有得到我想要的答案后,在这里寻找答案:

var matches = mystring.match(/(?:neededToMatchButNotWantedInResult)(matchWanted)/igm);

在查看了上面while和.push()的稍微复杂的函数调用之后,我发现这个问题可以用mystring.replace()非常优雅地解决(替换不是重点,甚至还没有完成,第二个参数的CLEAN内置递归函数调用选项是!):

var yourstring = 'something format_abc something format_def something format_ghi';

var matches = [];
yourstring.replace(/format_([^\s]+)/igm, function(m, p1){ matches.push(p1); } );

在这之后,我想我再也不会用.match()做任何事情了。