Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch the remainder of a regex .match()?

Is it possible, in JavaScript, to catch the remainder of a regex .match()?

For example:

var string = "505 Swanton St";

var m = string.match(/\d+/);

I can access "505" with m[0], but there are no other elements in m's array.

Is there a way to catch the remainder of string?

like image 848
Raphael Rafatpanah Avatar asked Dec 19 '22 07:12

Raphael Rafatpanah


2 Answers

You can catch everything before and after the pattern using capture groups:

var string = "505 Swanton St";

var m = string.match(/^(.*?)(\d+)(.*)$/);

Here:

m[0] == "505 Swanton St";  // the entire matched pattern
m[1] == "";                // first group
m[2] == "505";             // second group
m[3] == " Swanton St";     // third group

var string = "505 Swanton St";

var m = string.match(/^(.*?)(\d+)(.*)$/);

console.log(JSON.stringify(m));
like image 58
Paul Roub Avatar answered Dec 22 '22 00:12

Paul Roub


string.match and regexp.exec return special arrays with the added index property which is the index of the first character of the match. So you could also get the remainder with:

var string = "505 Swanton St";
var m = string.match(/\d+/);
var remainder = string.substring(0, m.index) + string.substring(m[0].length);

If used with a regex with the /g flag and the regex.exec function instead, you'll need to keep concatenating parts the between the end of a match and the beginning of the next.

function parseInput(input) {
  parseInput.regex.lastIndex = 0;
  var matches = [];
  var remainder = "";
  var prevIndex = 0;

  while((match = parseInput.regex.exec(input)) !== null) {
    matches.push(match);
    remainder += input.substring(prevIndex, match.index);
    prevIndex = parseInput.regex.lastIndex;
  }

  if(matches.length) {
    remainder += input.substring(prevIndex); // after last result
    return {"matches": matches, "remainder": remainder};
  } else {
    return {"matches": null, "remainder": input};
  }
}
parseInput.regex = /\d+/g;

I used this with a much more complex regex to parse all kinds of units. If there's an extraneous decimal point, my regex won't grab it and it will be in the remainder, so I can tell there's an error in the input by simply looking for points in the remainder.

* EDIT: Fixed the parseInput function so it also gets the remainder after the last match *

like image 28
Domino Avatar answered Dec 21 '22 23:12

Domino