Return the part of the regular expression that matches

A regular expression, which uses OR (pipe), is there any easy way to get part of the expression that fits.

Example:

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

returns Camel . I want Camel .

I understand that I could iterate over options instead of using one large regular expression; it will make more sense. But I am interested to know if this can be done like this.

+4
source share
3 answers

Very simple, no.

Regular expression matching refers to your input line, not the text used to create the regular expression. Please note that this text may well be lost and theoretically not even needed. An equivalent connector can be constructed from the following:

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

Another way to think about compiling regular expressions is to get the function logic out of their textual representation. It is unidirectional.

Unfortunately.

+5
source

There is no built-in tool in Javascript RegExp; without changing your expression. The closest you can get is source , which will simply return the whole expression as a string.

Since you know that you are an expression, this is a series | OR | OR s, you can capture the groups to find out which group was mapped, and combine this with .source to find out the contents of this group:

 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 very easy (albeit somewhat impractical) to write a RegExp engine from scratch, you could technically add this functionality. This will be much slower than using a real RegExp object, since the whole engine must be interpreted at run time. However, it could return the exact matched part of the expression for any regular expression and not be limited to what consists of a series of | OR | OR s.

However, the best way to solve your problem is probably not to use a loop or regular expression at all, but instead create an object in which you use the canonical form for the key:

 var matches = { 'horse': 'horse', 'camel': 'caMel', 'tortoise': 'TORTOISe' }; // Test "Camel" matches['Camel'.toLowerCase()]; // "caMel" 
+3
source

This will give the desired value without a loop:

 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 is no match, now you get undefined , although it is easy to change it to something else.

+2
source

Source: https://habr.com/ru/post/1244926/


All Articles