在使用OR
(管道)的正则表达式中,是否有一种方便的方法来获取匹配的表达式部分。
例子:
/horse|caMel|TORTOISe/i.exec("Camel");
返回Camel
。我想要的是caMel
。
我知道我可以遍历选项而不是使用一个大的正则表达式;那会更有意义。但我很想知道是否可以这样做。
在使用OR
(管道)的正则表达式中,是否有一种方便的方法来获取匹配的表达式部分。
例子:
/horse|caMel|TORTOISe/i.exec("Camel");
返回Camel
。我想要的是caMel
。
我知道我可以遍历选项而不是使用一个大的正则表达式;那会更有意义。但我很想知道是否可以这样做。
很简单,没有。
正则表达式匹配与您的输入字符串有关,而不是用于创建正则表达式的文本。请注意,该文本很可能会丢失,理论上甚至没有必要。一个等效的匹配器可以由这样的东西构建:
var test = function(str) {
var text = str.toLowerCase();
return text === "horse" || text === "camel" || text === "tortoise";
};
另一种思考方式是,正则表达式的编译可以将函数的逻辑与其文本表示分离。是单向的。
对不起。
Javascript RegExp 对象没有内置方法;不改变你的表情。你能得到的最接近的是source
将整个表达式作为字符串返回。
由于您知道您的表达式是一系列| OR
s,因此您可以捕获组以找出匹配的组,并将其结合.source
以找出该组的内容:
var exp = /(horse)|(caMel)|(TORTOISe)/i;
var result = exp.exec("Camel");
var match = function(){
for(var i = 1; i < result.length; i++){
if(result[i]){
return exp.source.match(new RegExp('(?:[^(]*\\((?!\\?\\:)){' + i + '}([^)]*)'))[1];
}
}
}();
// match == caMel
从头开始编写 RegExp 引擎也非常容易(尽管有些不切实际),您是否可以在技术上添加该功能。它比使用实际的 RegExp 对象要慢得多,因为必须在运行时解释整个引擎。但是,它能够准确地返回任何正则表达式的匹配部分,并且不限于由一系列| OR
s 组成的表达式。
但是,解决问题的最佳方法可能根本不使用循环或正则表达式,而是创建一个对象,在其中使用规范形式作为键:
var matches = {
'horse': 'horse',
'camel': 'caMel',
'tortoise': 'TORTOISe'
};
// Test "Camel"
matches['Camel'.toLowerCase()]; // "caMel"
这将在不循环的情况下给出想要的值:
var foo, pat, tres, res, reg = /horse|caMel|TORTOISe/i;
foo = reg.exec('Camel');
if (foo) {
foo = foo[0].replace(/\./g, '\\.');
pat = new RegExp('\\|' + foo + '\\|', 'i');
tres = '|' + reg.source + '|';
res = tres.match(pat)[0].replace(/\|/g, '');
}
alert(res);
如果没有匹配,现在你得到undefined
,虽然很容易改变到别的东西。