skip to Main Content

I need to replace a sequence of text inside a delimiter, exactly the number of times it occurs. E.g. I have a text like this:

"Cow says &moo;RGH but also &moo;moo;moo;RGH and &moo;moo;moo;moo;moo;RGH too but it doesn't moo; bah!"

I want to replace each "moo;" between "&" and "RGH" with an "A", so I expect that:

"Cow says &ARGH but also &AAARGH and &AAAAARGH but it doesn't moo; bah!"

In other words, I have to replace each "moo;" between "&" and "RGH" with an "A". I have to replace it via javascript on the whole text using a single regexp (if possible)
I did a lot of attempts, e.g.:

var a="Cow says &moo;RGH but also &moo;moo;moo;RGH and &moo;moo;moo;moo;moo;RGH but it doesn't moo; bah!"
a=a.replace(/(?<=&)((moo;)1?)+RGH/g,"A");
// a=a.replace(/&(moo;)+RGH/g,"A")
// a=a.replace(/&(?=moo;)1RGH/g,"A"
console.log(a);

but without evident success.
The idea is that each "moo;" must be replaced with "A" only if present along with other "moo;"s between a "&" and "RGH"

Any suggestion? Thanks!

2

Answers


  1. You can put (moo;)* into the lookbehind and lookahead assertion. That way the regex will match all moos between & and RGH:

    var a="Cow says &moo;RGH but also &moo;moo;moo;RGH and &moo;moo;moo;moo;moo;RGH but it doesn't moo; bah!"
    a=a.replace(/(?<=&(moo;)*)moo;(?=(moo;)*RGH)/g, 'A');
    console.log(a);

    And a benchmark:

    enter image description here

    <script benchmark data-count="1000000">
    
    let a = "Cow says &moo;RGH but also &moo;moo;moo;RGH and &moo;moo;moo;moo;moo;RGH too but it doesn't moo; bah!";
    
    // @benchmark Unmitigated
    a.replace(/(?<=&)(moo;)+(?=RGH)/g, m => 'A'.repeat(m.length / 4));
    
    // @benchmark Alexander
    a.replace(/(?<=&(moo;)*)(moo;)(?=(moo;)*RGH)/g, 'A');
    
    </script>
    <script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>
    Login or Signup to reply.
  2. You can also match all the consecutive sequences of moo; and pass a callback to String#replace that replaces each sequence based on its length.

    let str = "Cow says &moo;RGH but also &moo;moo;moo;RGH and &moo;moo;moo;moo;moo;RGH too but it doesn't moo; bah!";
    let res = str.replace(/(?<=&)(moo;)+(?=RGH)/g, m => 'A'.repeat(m.length / 4));
    console.log(res);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search