Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS RegExp capture all groups and pos for each match

Statement: I am new to RegExp and trying to learn capture groups in javascripts

  1. I am using https://regex101.com/r/COYhIc/1 for testing
  2. see attached image for character pos column of each match by https://regex101.com

Objective:

  1. I want to print all matches and groups at console (Done)
  2. I want to print character position of each match [see image](remaining)

enter image description here

JSFIDDLE: https://jsfiddle.net/bababalcksheep/p28fmdk4/68/

JavaScript:

function parseQuery(query) {
  var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
  if (isRE) {
    try {
      query = new RegExp(isRE[1], isRE[2]);
    } catch (e) {}
  }
  return query;
}
var str = $('#str').val();
var regex = parseQuery($('#reg').val());
//
var result;
var match_no = 0;
var output = '';
while ((result = regex.exec(str)) !== null) {
  match_no++;
  output += `\nMatch ${match_no}\n`;
  output += `Full Match, ${ result[0]} , Pos\n`;
  for (i = 1; i < result.length; i++) {
    output += `Group ${i}, ${ result[i]} , Pos\n`;
  }
}
console.log(output);
like image 880
django Avatar asked Dec 09 '25 19:12

django


2 Answers

In your output field use index and lastIndex. exec returns an object with a index property.

output += `Full Match, ${ result[0]} , Pos ${result.index} - ${regex.lastIndex}\n `;

Update for the groups:

I have used a small logic to get the indices:

var m = new RegExp(result[i]);
output += `Group ${i}, ${ result[i]}, Pos ${$('#str').val().match(m).index} - ${regex.lastIndex} \n`;

function parseQuery(query) {
  var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
  if (isRE) {
    try {
      query = new RegExp(isRE[1], isRE[2]);
    } catch (e) {}
  }
  return query;
}
var str = $('#str').val();
var regex = parseQuery($('#reg').val());
//
var result;
var match_no = 0;
var output = '';
while ((result = regex.exec(str)) !== null) {
  match_no++;
  output += `\nMatch ${match_no}\n`;
  output += `Full Match, ${ result[0]} , Pos ${result.index} - ${regex.lastIndex}\n `;
  for (i = 1; i < result.length; i++) {
    var m = new RegExp(result[i]);
    output += `Group ${i}, ${ result[i]}, Pos ${$('#str').val().match(m).index} - ${regex.lastIndex} \n`;
  }
}
console.log(output);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div class="form-group">
    <label for="str">String:</label>
    <input type="text" class="form-control" id="str" value="source=100, delta=2, source=2121, delta=5">
  </div>
  <div class="form-group">
    <label for="regex">Regex:</label>
    <input type="text" class="form-control" id="reg" value="/(source=(\d+))/g">
  </div>
  <div id="result">

  </div>
</div>

FIDDLE

like image 129
Tushar Avatar answered Dec 11 '25 08:12

Tushar


According to docs RegExp.exec, you can retrieve it using index property. So I would add this line into your snippet to retrieve column position for your full match:

`${result.index}-${result.index + result[0].length}`

For subgroups, JS doesn't retrieve index, so a workaround can be achieved using indexOf:

const initialSubGroupIndex = str.indexOf(result[i], result.index);
`${initialSubGroupIndex}-${initialSubGroupIndex + result[i].length}`
like image 21
guijob Avatar answered Dec 11 '25 08:12

guijob



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!