如何突出显示任意数量的(可能重复的)a,然后是非贪婪匹配器,然后是任意数量的b等(没有不合理的限制)

How to highlight any amount of (possibly duplicated) As, followed by non-greedy matcher, then by any amount of Bs etc. (without unreasonable limits)?

本文关键字:然后 任意数 不合理 贪婪 显示 是非 何突出      更新时间:2023-09-26

下面的例子是我想要的突出显示类型的演示("a", "b", "c""d"):

var reg = new RegExp("(.*?)([a]{1,})(.*?)([b]{1,})(.*?)([c]{1,})(.*?)([d]{1,})(.*?)", "gi");
var txt = "OK, abacd, abcdt, yaaaxxbyycccczzddddg0011".replace(reg,
  '$1<mark>$2</mark>$3<mark>$4</mark>$5<mark>$6</mark>$7<mark>$8</mark>$9');
document.getElementById("test").innerHTML = txt;
<body>
  <div id="test"></div>
</body>

这里的问题显然是$nn=9的限制。但是,如果我想为超过4个字符执行此操作(即没有不合理的限制),该怎么办?如何解决这个问题?

尝试使用function作为replace()

参数

这更像@WiktorStribiżew

提到的动态模式

var reg = new RegExp(["a", "b", "c", "d"].map(a => "([" + a + "]{1,})(.*?)").reduce((a, i) => a + i, "(.*?)"), "gi");
var txt1 = "OK, abacd, abcdt, yaaaxxbyycccczzddddg0011"
  .replace(reg, (m, ...p) => {
    p.pop();//pop string
    p.pop();//pop offset
    return p.reduce((a, i, ix) => a + (ix % 2 ? "<mark>" + i + '</mark>' : i), '')
  });
var txt = "OK, abacd, abcdt, yaaaxxbyycccczzddddg0011"
  .replace(reg, (m, ...p) => {
    p.pop();
    p.pop();
    return "<br><br>-match-" + m + p.reduce((a, i, ix) => a + "<br>-substring-" + (ix % 2 ? i : "-h-" + i), '')
  });
document.getElementById("test").innerHTML = txt1 + txt;
<body>
  <div id="test"></div>
</body>

Regex不会给你整个解决方案,它只能是解决方案的一部分。使用regex隔离单个匹配,然后遍历这些匹配并逐一进行替换。在这种情况下,迭代是通过将函数定义传递给.replace()来完成的,该函数本身有另一个for循环来完成实际的替换。

我也简化了正则表达式,[a]只是a, {1,}相当于+。然后,如果你只是把你想要匹配的字符放在一个数组中,你可以.join()它们一起使正则表达式,以及这个数组在函数内部使用,从最后的<mark>...</mark> 向后到第一个。倒推有助于确保找到的a仍然在整个匹配的前面,直到最后插入<mark>...</mark>。它还可以防止获得像<mar<mark>k</mark>>这样的东西(我将'k'添加到数组的原因是为了测试这一点)。

您可以看到没有一个正则表达式高于$2,即使代码突出显示了chars数组中的5个字符。您可以使这个数组任意长以满足您的需要。我还添加了一个<textarea>,这样您就可以看到在for -循环中生成的正则表达式。

var chars = ['a', 'a', 'b', 'c', 'd', 'k'];
var fillr = '+[^<]*?';
var txt = "OK, abacdk, abcdtk, yaaaxxbyycccczzddddgkkkk0011"
  .replace(new RegExp(chars.join(fillr) + '+', 'gi'),
    function(m) {
      for (var i = chars.length-1; i >= 0; i--) {
        var rgx = '^' +
          ((i!=0)?
            ('(' + chars.slice(0, i).join(fillr) + fillr + ')'):
            '()'
          ) +
          '('+chars[i]+'+)';
        document.getElementById('srccode').value += i + ''t' + m + ''n't' + rgx + ''n';
        m = m.replace(new RegExp(rgx, 'gi'), '$1<mark>$2</mark>');
        document.getElementById('srccode').value += ''t' + m + ''n'n';
      }
      return m.replace(/<'/mark>('s*)<mark>/gi, '$1');
    }
  );
document.getElementById('srccode').value += ''n'+txt;
document.getElementById("test").innerHTML = txt;
<body>
  <textarea id="srccode" rows="10" style="width:100%;white-space: nowrap; overflow:scroll;"></textarea>
  <div id="test"></div>
</body>

相关文章: