How to use regex starting in the middle of the string?

Asked

Viewed 211 times

4

I have a rather large string and would like to check if an excerpt of it house with a regex. The problem is that this stretch is in the middle of the string, in a very specific position. As I will have to do this several times (different strings, different regexes and different positions) I would like this check to be done efficiently, without having to:

  1. Make a substring, which would create new strings unnecessarily:

    var sub = str.substring(pos); // Cria um novo objeto, potencialmente bem grande
    regex.exec(sub);
    

    or:

  2. Do the search globally, which not only traverses parts of the string that do not interest me (i.e. those before the desired position) but also may not give me the result I want at all (e.g. : if there is an intersection between a previous match and the part of the string that interests me):

    var resultado = regex.exec(str); // Assumindo que regex possui a flag g
    while ( resultado && resultado.index < pos )
        resultado = regex.exec(str);
    if ( resultado.index == pos )
        ...
    

Is it possible to do this? The usual methods of marriage (String.match, RegExp.test and RegExp.exec) do not have parameters to specify the position of the string from which to start the execution, and even the String.search does not have this option. There is some other way?

1 answer

6


This can be done through flag sticky and property lastIndex (the same one used by flag global). Just create the regex with this flag and then assign the position you want to seek:

var re = /\w+/y;
var str = "....abc....def...";

re.lastIndex = 4;
console.log(re.exec(str)); // ["abc"]

re.lastIndex = 11;
console.log(re.exec(str)); // ["def"]

re.lastIndex = 2;
console.log(re.exec(str)); // null

re.lastIndex = 5; // Funciona em qualquer índice
console.log(re.exec(str)); // ["bc"]

(Note: that flag was only recently standardized by ES2015, so that is only supported by browsers in their latest versions, and support on mobile platforms is still limited)

This flag is required because: a) if the regex is not global, the value of the property lastIndex is ignored; b) if a regex is global, it searches from the lastIndex, instead of starting the wedding on lastIndex (and no use ^ at the beginning of regex, since it is not at the beginning of the string, the execution will fail):

var str = "....abc....def....";

var re1 = /\w+/;
re1.lastIndex = 11; // Deveria pegar a segunda palavra
console.log(re1.exec(str)); // ["abc"]

var re2 = /\w+/g;
re2.lastIndex = 2; // Deveria falhar
console.log(re2.exec(str)); // ["abc"]

var re3 = /^\w+/g;
re3.lastIndex = 11; // Deveria pegar a segunda palavra
console.log(re3.exec(str)); // null

  • 1

    Note that the flag /y not supported by all browsers

  • 1

    @Mariano De facto. This flag has been used in Firefox for years, but has only been standardized by ES6. Currently all modern desktop browsers support - including Edge, but excluding IE in all its versions. On mobile platforms, only iOS 10 for now... I will update the answer with this information.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.