解析CGI查询字符串正则表达式

Parsing CGI Query String Regex

本文关键字:正则表达式 字符串 查询 CGI 解析      更新时间:2023-09-26

解析查询字符串数据的一种方法是:

GLOBAL={}
"?a=1&b=3&D123=Hello world".replace(
  new RegExp(/([^?=&]+)(=([^&]*))?/g),
  function($0, $1, $2, $3) {
    GLOBAL[$1]=$3
  }
)

我是RegEx的新手,想知道是否有人可以解释RegEx表达式如何与变量$0,$1,$2,$3一起工作,使其在本例中GLOBAL[a] = 1。

如果$1 =第一个分组,$2 =第二个分组,等等。0美元的需求是什么?

通常认为给回调参数起有意义的名字是更好的做法,特别是为了帮助理解。就我个人而言,我会将您的代码编写为:

... .replace(
    /([^?=&]+)(?:=([^&]*))?/g, // note slightly different regex ;)
    function( _, key, value) {
        GLOBALS[key] = value;
    }
);

看,仅仅通过阅读来理解发生了什么要容易得多?_是一个约定,意思是"我们对这个参数不感兴趣"(这使得"下划线"库对我来说很可笑……XD)

在任何情况下,与所有回调函数一样,形参完全取决于函数决定传递什么。在.replace()的情况下,第一个参数是整个匹配,然后从那时起捕获的子模式一个接一个地给定-这就是为什么我在评论中说有"太多括号",您可以看到在我的版本中,我使用(?:指定非捕获子模式。

正如已经回答的那样,您的$0变量将包含由整个表达式匹配的部分输入字符串,而不是括号中的匹配。

至于你想做什么,你可以使用一个替换回调来填充GLOBALS对象,但是为了填充不止第一个参数,尝试如下:

var GLOBALS = {},
    query = "?a=1&b=3&D123=Hello world",
    expr = /^(?:'?|&)([^=&]*)(?:=([^&]*))?/g;
while( query = query.replace( expr, function( match, prop, value ){
    GLOBALS[ decodeURIComponent(prop||'') ] = decodeURIComponent(value||'');
    return '';
} ) );

这允许在字符串中有任意数量的参数,但是如果查询格式不好,您可能会得到一个无限循环,因为它不会停止,直到输入字符串耗尽。

风险较小的是:

while( match = /^(?:'?|&)([^=&]*)(?:=([^&]*))?/g.exec(query) ){
    query = query.substr( match[0].length );
    GLOBALS[ decodeURIComponent(match[1]||'') ] = decodeURIComponent(match[2]||'');
}

然而,用RegExp匹配每个参数可能不是最好的方法。就我个人而言,我会这样做:

var pairs = query.split(/['?&]/), pair, p;
for( p in pairs ){
     if( pairs[p] ){
        pair = pairs[p].split('=',2);
        GLOBALS[ decodeURIComponent(pair[0]||'') ] = decodeURIComponent(pair[1]||'');
    }
}