Marek
Marek

Reputation: 23

Javascript regex: dynamic capture group

I'm trying to wrap my mind around regex for the first time.

For the string

I want you to MATCH THIS, you bastard regex, but also MATCH X THIS and yeah,
MATCH X X X THIS too.

Basically, a starting pattern, an end pattern and an arbitrary number of a pattern inbetween.

So I'd like a myregex.exec string to successively return

["MATCH", "THIS"]
["MATCH", "X", "THIS"]
["MATCH", "X", "X", "X", "THIS"]

I've tried variations of this

/(MATCH)\s+(X)?\s+(THIS)/

but no cigar...

Upvotes: 2

Views: 1466

Answers (2)

MT0
MT0

Reputation: 167832

You can use the regular expression to match the entire expression:

/MATCH\s+(?:X\s+)*THIS/g

To get it into an array of terms/words you can then use String.split() like this:

var out = document.getElementById( "out" );

function parse( string ){
  var re = /MATCH\s+(?:X\s+)*THIS/g;
  var matches = (string.match( re ) || [])
                  .map( function(m){ return m.split( /\s+/ ); } );
  out.innerHTML = JSON.stringify( matches );
}

parse( document.getElementById( "in" ).value );
textarea { width: 100%; }
<textarea id="in" onchange="parse( this.value )">I want you to MATCH THIS, you bad regex, but also MATCH X THIS and yeah, MATCH X X X THIS too.</textarea>
<p id="out"/>

Upvotes: 2

Joe
Joe

Reputation: 917

Try putting the \s+ into the optional group with *:

/(MATCH)\s+(?:(X)\s)*(THIS)/g

Note the g modifier to get all matches.

Upvotes: 1

Related Questions