views:

34

answers:

3

Hi ,

I spent lot time figuring out a simple regex to return a group (only 1st group).

So the string can be - "No purchase required" or "Purchase of $50.00 worth groceries is required."

I am trying to write a regex which can parse "No" or "50" based on the given string.

This is what I have written.

(?:(No) monthly maintenance|Purchase of \$([\d\.]+ worth groceries)

This works fine but I want my output as 1st group/group 1 only.

+1  A: 

Why not just use /(?:No monthly maintenance|Purchase of $([0-9.]+) worth groceries)/.

The match will fail if it's not in one of those formats, and Group 1 matches '' for the "No monthly maintenance" case, or the number for other case.

If you really need to capture the string No or the number, you might need to get a little more complicated and do something like:

/(?:Purchase of $)?([0-9.]+|No) (?:monthly maintenance|worth groceries)/
gnarf
+1  A: 

Most languages count the matching groups in order, regardless of whether they are in a non-capturing group ((?:...|...)), so forcing the interesting part into the first capturing group might be more trouble than it's worth.

Depending on what language you are using you might want to try using two different precompiled regular expressions and return the matching group of the first match, that way you can easily fit the interesting part into the first group.

maerics
A: 

I'm not sure you can get the result in group number 1, but you can get both results to appear in the same named group. Here's an example in PowerShell:

$input1 = 'Purchase of $50.00 worth groceries is required'
$input2 = 'No monthly maintenance required'

$re = '(?:(?<xyz>No) monthly maintenance|Purchase of \$(?<xyz>[\d\.]+) worth groceries)'

$match = [regex]::Match($input1, $re)
$match.Groups['xyz']

$match = [regex]::Match($input2, $re)
$match.Groups['xyz']

Which results in the following:

Success  : True
Captures : {50.00}
Index    : 13
Length   : 5
Value    : 50.00

Success  : True
Captures : {No}
Index    : 0
Length   : 2
Value    : No

Not all languages support named groups though. Since PowerShell runs on the .NET Framework, this will work for any .NET language.

Damian Powell
Named groups are pretty common these days, but very few flavors permit using the same name twice in one regex, like you did. Which is a shame, because that's a very handy feature.
Alan Moore