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

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”)有一个特殊值,所以它试图查找下一个参数的值。


当前回答

函数getMatches(字符串、正则表达式、索引){索引||(索引=1);//默认为第一个捕获组var matches=[];var匹配;while(match=regex.exec(字符串)){matches.push(match[index]);}返回匹配;}//示例:var myString='200卢比记入账户。。。2031年2月12日20:05:49(结算余额66248.77卢比)ATM。免费电话180022334418001024455(上午6点至晚上10点);var myRegEx=/清除bal.+?(\d+\.?\d{2})/gi;//获取包含每个匹配的第一个捕获组的数组var matches=getMatches(myString,myRegEx,1);//日志结果document.write(matches.length+'找到匹配项:'+JSON.stringify(匹配项))console.log(匹配项);

函数getMatches(字符串、正则表达式、索引){索引||(索引=1);//默认为第一个捕获组var matches=[];var匹配;while(match=regex.exec(字符串)){matches.push(match[index]);}返回匹配;}//示例:var myString=“something format_abc something format_def something form_ghi”;var myRegEx=/(?:^|\s)format_(.*?)(?:\s|$)/g;//获取包含每个匹配的第一个捕获组的数组var matches=getMatches(myString,myRegEx,1);//日志结果document.write(matches.length+'找到匹配项:'+JSON.stringify(匹配项))console.log(匹配项);

其他回答

您的语法可能不是最好保留的。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"]

var myString=“something format_abc”;var arr=myString.match(/\bformat_(.*?)\b/);控制台日志(arr[0]+“”+arr[1]);

\b并不完全相同。(它适用于--format_foo/,但不适用于format_a_b)但我想展示一个替代表达式,这很好。当然,比赛电话是最重要的。

我们可以通过使用反斜杠后跟匹配组的编号来访问正则表达式中的匹配组:

/([a-z])\1/

在由第一组([a-z])匹配的代码\ 1中

如果你和我一样,希望正则表达式返回这样的Object:

{
    match: '...',
    matchAtIndex: 0,
    capturedGroups: [ '...', '...' ]
}

然后从下面剪切函数

/***@param{string | number}输入*要匹配的输入字符串*@param{regex | string}表达式*正则表达式*@param{string}标志*可选标志* *@return{array}* [{匹配:“…”,matchAtIndex:0,捕获的组:[“…”,“…”]}] */函数regexMatch(输入,表达式,标志=“g”){让regex=RegExp的表达式实例?表达式:新RegExp(表达式,标志)let matches=input.matchAll(正则表达式)匹配=[…匹配]return matches.map(项=>{返回{匹配:项[0],matchAtIndex:项索引,捕获组:item.length>1?item.s切片(1):未定义}})}let input=“key1:value1,key2:value2”让正则表达式=/(\w+):(\w+)/glet matches=regexMatch(输入,regex)console.log(匹配项)

使用es2018,您现在可以对命名组使用String.match(),使正则表达式更明确地说明它要做什么。

const url =
  'https://stackoverflow.com/questions/432493/how-do-you-access-the-matched-groups-in-a-javascript-regular-expression?some=parameter';
const regex = /(?<protocol>https?):\/\/(?<hostname>[\w-\.]*)\/(?<pathname>[\w-\./]+)\??(?<querystring>.*?)?$/;
const { groups: segments } = url.match(regex);
console.log(segments);

你会得到类似的东西

{protocol:“https”,主机名:“stackerflow.com”,路径名:“questions/432493/how-do-you-acess-the-matched-groups-in-a-javascript-regular-expression”,querystring:“some=parameter”}