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

4

I have a fairly large string and would like to check if a snippet of it matches a regex. The problem is that this snippet 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:

  • 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:

  • Do the search globally, which not only traverses parts of the string that do not interest me (ie those before the desired position) but also may not give me the result I want at all (eg if there is an intersection between a marriage 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 wedding methods ( String.match , RegExp.test and RegExp.exec ) do not have parameters to specify the position of the string from which to start execution, and even String.search does not have this option. Is there any other way?

        
    asked by anonymous 11.01.2017 / 07:39

    1 answer

    6

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

    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: this flag was only recently standardized by ES2015, so 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 lastIndex property is ignored; b) if regex is global, it searches from lastIndex , instead of starting marriage exactly in lastIndex (and it's no use using ^ at the beginning of regex, because since it's not at the beginning of the string , 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
        
    11.01.2017 / 07:39