【问题标题】:JS RegExp capture all groups and pos for each matchJS RegExp 捕获每场比赛的所有组和位置
【发布时间】:2019-07-26 10:23:12
【问题描述】:

声明: 我是 RegExp 的新手,正在尝试学习 javascripts 中的捕获组

  1. 我正在使用https://regex101.com/r/COYhIc/1 进行测试
  2. https://regex101.com 的每个匹配的字符 pos 列见附图

目标:

  1. 我想在控制台打印所有匹配项和组(完成)
  2. 我想打印每个匹配的字符位置 [见图](剩余)

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);

【问题讨论】:

标签: javascript regex


【解决方案1】:

在您的输出字段中使用index 和lastIndex。 exec 返回一个具有索引属性的对象。

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

小组更新:

我使用了一个小逻辑来获取索引:

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

【讨论】:

  • 组呢?完全匹配可以,但不能用于第 2 组
  • 使用小提琴 jsfiddle.net/bababalcksheep/p28fmdk4/68 ,我将其更新为与 regex101.com/r/COYhIc/1 完全匹配,并查看第 2 组的区别
  • @django 更新了答案!
  • 仅供参考,我使用了旧的 js fiddle,但效果很好。 :)
  • 没有一个解决方案可以通过测试用例 str = aaaaaaaaaaaaaa, regex = /a(a*)a/g。根本不可能找到子组的索引 - 你只能在捕获的字符串在匹配中只出现一次时才能做到这一点
【解决方案2】:

根据文档RegExp.exec,您可以使用index 属性检索它。所以我会将此行添加到您的 sn-p 以检索您的完整匹配的列位置:

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

对于子组,JS 不检索索引,因此可以使用 indexOf 实现解决方法:

const initialSubGroupIndex = str.indexOf(result[i], result.index);
`${initialSubGroupIndex}-${initialSubGroupIndex + result[i].length}`

【讨论】:

  • 但是第 1 组和第 2 组呢?我有问题,完全匹配是正确的,但其余的都磨损了
  • @django 不幸的是,js 默认不提供访问组的索引,在您的情况下我会做的是在您的实际字符串str 中搜索您找到的组结果[1] 和结果[2]。类似str.indexOf(result[1])
  • 使用小提琴 jsfiddle.net/bababalcksheep/p28fmdk4/68 ,我将其更新为与 regex101.com/r/COYhIc/1 完全匹配,并查看第 2 组的区别
  • str.indexOf(result[1]) 可以产生磨损结果,因为值 100 的组 2 重复两次
  • @django 是的,这是使用indexOf 的第二个参数的好机会:jsfiddle.net/tyje1zbc
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 1970-01-01
  • 2020-11-11
  • 1970-01-01
  • 2019-04-09
  • 2013-11-01
相关资源
最近更新 更多