Marl
Marl

Reputation: 1504

Javascript: String search for regex, starting at the end of the string

Is there a javascript string function that search a regex and it will start the search at the end?

If not, what is the fastest and/or cleanest way to search the index of a regex starting from the end?

example of regex:

/<\/?([a-z][a-z0-9]*)\b[^>]*>?/gi

Upvotes: 6

Views: 10768

Answers (7)

Raul Bejarano
Raul Bejarano

Reputation: 86

Maybe this can be useful and easier:

str.lastIndexOf(str.match(<your_regex_here>).pop());

Upvotes: 4

MC ND
MC ND

Reputation: 70923

var m = text.match(/.*(<\/?([a-z][a-z0-9]*)\b[^>]*>?)/i);
if (m) {
    textFound = m[1];
    position = text.lastIndexOf(textFound);
}

Use .* to skip as much text as posible, capture the text found and search it with lastIndexOf

EDIT:

Well, if text is found, no need to search with lastIndexOf. m[0] contains the full coincidence (including all the initial padding), and m[1] the searched text. So position of found text is m[0].length - m[1].length

var m = text.match(/.*(<\/?([a-z][a-z0-9]*)\b[^>]*>?)/i);
if (m) {
    textFound = m[1];
    position = m[0].length - m[1].length;
}

Upvotes: 0

Xotic750
Xotic750

Reputation: 23472

Perhaps something like this is suitable for you?

Javascript

function lastIndexOfRx(string, regex) {
    var match = string.match(regex);

    return  match ? string.lastIndexOf(match.slice(-1)) : -1;
}

var rx = /<\/?([a-z][a-z0-9]*)\b[^>]*>?/gi;

console.log(lastIndexOfRx("", rx));
console.log(lastIndexOfRx("<i>it</i><b>bo</b>", rx));

jsFiddle

And just for interest, this function vs the function that you choose to go with. jsperf

This requires that you format your regex correctly for matching exactly the pattern you want and globally (like given in your question), for example /.*(<\/?([a-z][a-z0-9]*)\b[^>]*>?)/i will not work with this function. But what you do get is a function that is clean and fast.

Upvotes: 2

Marl
Marl

Reputation: 1504

Andreas gave this from the comment:

https://stackoverflow.com/a/274094/402037

String.prototype.regexLastIndexOf = function(regex, startpos) {
    regex = (regex.global) ? regex : new RegExp(regex.source, "g" + (regex.ignoreCase ? "i" : "") + (regex.multiLine ? "m" : ""));
    if(typeof (startpos) == "undefined") {
        startpos = this.length;
    } else if(startpos < 0) {
        startpos = 0;
    }
    var stringToWorkWith = this.substring(0, startpos + 1);
    var lastIndexOf = -1;
    var nextStop = 0;
    while((result = regex.exec(stringToWorkWith)) != null) {
        lastIndexOf = result.index;
        regex.lastIndex = ++nextStop;
    }
    return lastIndexOf;
}

Which gives the functionality that I need, I tested my regex, and it is successful. So I'll use this

Upvotes: 1

Snake Eyes
Snake Eyes

Reputation: 16754

You may create a reverse function like:

function reverse (s) {
  var o = '';
  for (var i = s.length - 1; i >= 0; i--)
    o += s[i];
  return o;
}

and then use

var yourString = reverse("Your string goes here");
var regex = new Regex(your_expression);
var result = yourString.match(regex);

Another idea: if you want to search by word in reverse order then

function reverseWord(s) {
   var o = '';
   var split = s.split(' ');

  for (var i = split.length - 1; i >= 0; i--)
    o += split[i] + ' ';
  return o;
}

var yourString = reverseWord("Your string goes here");
var regex = new Regex(your_expression);
var result = yourString.match(regex);

Upvotes: 1

micnic
micnic

Reputation: 11245

It depends what you exactly want to search for. You can use string.lastIndexOf or inside the regexp to use $ (end of the string).

Update: try the regexp

/<\/?([a-z][a-z0-9]*)\b[^>]*>?[\w\W]*$/gi

Upvotes: 0

ErnestV
ErnestV

Reputation: 137

Assuming you're looking for a string 'token', then you need the position of 'token' that has no other 'token' following until the end of the string.

So you should compose your regex something like that:

$token = 'token';
$re = "/(?:$token)[^(?:$token)]*$/";

This will find your 'token' where no further 'token' can be found until string end. The "(?:" grouping simply makes the group non-storing, slightly speeding up performance and saving memory.

Upvotes: -1

Related Questions