MedicineMan
MedicineMan

Reputation: 15314

regular expression in javascript, detecting optional arguments

I'm doing replacements on some tokenized strings like below:

var myString = "I would like to replace the following token <<start<arg1,arg2 >>> in this string"
OR  
var myString = "The expression has an optional <<start<arg1,arg2,arg3 >>> third argument" 

Within the token, there are 2 or 3 alphanumeric strings which I would like to capture and pass to the regex callback function:

myString.replace(regExExpression, function(m, arg1, arg2, arg3) { 
   return foo(arg1, arg2, arg3); 
});

What regex expression will match both versions of myString, capture arg1, arg2, and the optional arg3?

Upvotes: 0

Views: 106

Answers (3)

Ro Yo Mi
Ro Yo Mi

Reputation: 15000

Description

Try this which will put each arg into a group 1 2 or 3 respectively, see also this regexplanet sample

  • Each attribute group starts with <<start< and ends with >>>
  • Will match between 2 and 3 groups of comma delimited substrings between the open and close tags, additional groups could be matched by inserting (?:,([^,>]*))? between the second and third groups.
  • Token 3 is optional

<<start<([^,>]*)(?:,([^,>]*))(?:,([^>]*))?(?=>>>)

enter image description here

Upvotes: 1

HBP
HBP

Reputation: 16033

I following handles your specific case:

  /<<\s*start\s*<\s*(?:([^,>]*))?(?:\s*,\s*([^,>]*))?(?:\s*,\s*([^>]*))?>>>/i

I usually sprinkle my REs with \s* to accept free form input. Remove them if you are sure not to need them. I do not think that you can write a single RE to handle an arbitrary number of arguments but you specified a maximum of 3.

My recommendation would be to use the following two stage solution which gives you the extra flexibility of an arbitrary number of arguments :

  .replace (/<<\s*start\s*<\s*(.*)?\s*>>>/i, function (m, args) {
     args = args.split (/\s*,\s*/); // array of args
     return  ('{{[' + args.length + '] : ' + args.join (', ') + '}}');
  });

And used as follows :

"I would like to replace the following token <<start<arg1,arg2 , arg3>>> in this string".replace (/<<\s*start\s*<\s*(.*)?\s*>>>/i, function (m, args) {
         args = args.split (/\s*,\s*/); // arbitrary number of
         return  ('{{[' + args.length + '] : ' + args.join (', ') + '}}');
      });

Resulting in :

"I would like to replace the following token {{[3] : arg1, arg2, arg3}} in this string"

Upvotes: 0

Explosion Pills
Explosion Pills

Reputation: 191749

I think you just want the regex

/<<(.*?)>>>/g

This should also work if there are multiple samples per line, but not if they are nested. If that doesn't cover your actual question, it's because it's a bit unclear.

Upvotes: 0

Related Questions