Javascript 解析CGI查询字符串Regex
解析查询字符串数据的一种方法是:Javascript 解析CGI查询字符串Regex,javascript,regex,Javascript,Regex,解析查询字符串数据的一种方法是: GLOBAL={} "?a=1&b=3&D123=Hello world".replace( new RegExp(/([^?=&]+)(=([^&]*))?/g), function($0, $1, $2, $3) { GLOBAL[$1]=$3 } ) 我不熟悉正则表达式,想知道是否有人可以解释正则表达式如何使用变量$0、$1、$2、$3,使其在本例中的全局[a]=1 如果$1=第一个分组,$2=第二个分
GLOBAL={}
"?a=1&b=3&D123=Hello world".replace(
new RegExp(/([^?=&]+)(=([^&]*))?/g),
function($0, $1, $2, $3) {
GLOBAL[$1]=$3
}
)
我不熟悉正则表达式,想知道是否有人可以解释正则表达式如何使用变量$0、$1、$2、$3,使其在本例中的全局[a]=1
如果$1=第一个分组,$2=第二个分组,等等。那么$0的必要性是什么?通常认为,更好的做法是为回调参数指定有意义的名称,特别是为了帮助理解。就个人而言,我会将您的代码编写为:
... .replace(
/([^?=&]+)(?:=([^&]*))?/g, // note slightly different regex ;)
function( _, key, value) {
GLOBALS[key] = value;
}
);
看看仅仅通过阅读理解发生了什么是多么容易u
是一种约定,意思是“我们对这个参数不感兴趣”(这使得“下划线”库对我来说很可笑…XD)
在任何情况下,与所有回调一样,参数完全取决于函数决定传递的内容。在
.replace()
的情况下,第一个参数是整个匹配,然后从那时起,捕获的子模式一个接一个地给出-这就是为什么我说我的注释中有“太多括号”,你可以在我使用的版本中看到(?:
指定一个非捕获子模式。正如已经回答的,您的$0
变量将包含输入字符串中由整个表达式匹配的部分,而不是括号中的匹配项
至于您尝试执行的操作,您可以使用replace回调来填充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]||'');
}
}
很多在线工具已经提供了这样的功能:,…你试过其中一些吗?我应该重新编写我的问题。我真的不明白它是如何与变量一起存储正确的名称:值对的。正则表达式中有太多的括号…但无论如何,它只是一个基本回调。参数是根据函数,在本例中为
replace
。非常感谢!我将来肯定会使用有意义的名称。