简体   繁体   English

返回匹配的正则表达式的部分

[英]Return the part of the regex that matched

In a regular expression that uses OR (pipe), is there a convenient method for getting the part of the expression that matched. 在使用OR (管道)的正则表达式中,是否有一种方便的方法来获取匹配的表达式部分。

Example: 例:

/horse|caMel|TORTOISe/i.exec("Camel");

returns Camel . 回归Camel What I want is caMel . 我想要的是caMel

I understand that I could loop through the options instead of using one big regular expression; 我知道我可以遍历选项而不是使用一个大的正则表达式; that would make far more sense. 这会更有意义。 But I'm interested to know if it can be done this way. 但我很想知道它是否可以这样做。

Very simply, no. 非常简单,没有。

Regex matches have to do with your input string and not the text used to create the regular expression. 正则表达式匹配与输入字符串有关,而不是用于创建正则表达式的文本。 Note that that text might well be lost, and theoretically is not even necessary. 请注意,该文本可能会丢失,理论上甚至不需要。 An equivalent matcher could be built out of something like this: 一个等效的匹配器可以用这样的东西构建:

var test = function(str) {
    var text = str.toLowerCase();
    return text === "horse" || text === "camel" || text === "tortoise";
};

Another way to think of it is that the compilation of regular expressions can divorce the logic of the function from their textual representation. 另一种思考方式是正则表达式的编译可以将函数的逻辑与其文本表示分开。 It's one-directional. 这是单向的。

Sorry. 抱歉。

There is not a way built-in to the Javascript RegExp object; Javascript RegExp对象没有内置的方法; without changing your expression. 没有改变你的表达。 The closest you can get is source which will just return the entire expression as a string. 您可以获得的最接近的是source ,它将整个表达式作为字符串返回。

Since you know you're expression is a series of | OR 既然你知道你的表达是一系列的| OR | OR s, you could capturing groups to figure out which group matched, and combine that with .source to find out the contents of that group: | OR ,您可以捕获组以确定哪个组匹配,并将其与.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

It is also extremely easy (although somewhat impractical) to write a RegExp engine from scratch would you could technically add that functionality to. 从头开始编写RegExp引擎也非常容易(虽然有些不切实际),您可以在技术上添加该功能。 It would be much slower than using an actual RegExp object, since the whole engine would have to be interpreted at run-time. 它比使用实际的RegExp对象要慢得多,因为必须在运行时解释整个引擎。 It would, however, be able to return exactly the matched portion of the expression for any regular expression and not be limited to one which consists of a series of | OR 但是,它能够准确地返回任何正则表达式的表达式的匹配部分,而不仅限于由一系列| OR | OR s. | OR s。

The best way to solve your problem, however, is probably not to use a loop or a regular expression at all, but instead to create an object where you use a canonical form for the key: 但是,解决问题的最佳方法可能根本不是使用循环或正则表达式,而是创建一个对象使用规范形式的对象:

var matches = {
  'horse': 'horse',
  'camel': 'caMel',
  'tortoise': 'TORTOISe'
};

// Test "Camel"
matches['Camel'.toLowerCase()]; // "caMel"

This will give the wanted value without looping: 这将给出想要的值而不循环:

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);

If there's no match, now you get undefined , though it's easy to change to something else. 如果没有匹配,现在你得到了undefined ,虽然很容易改变别的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM