Start capturing on right and not left

Viewed 20

I have the following RE that needs to match starting on the end of the string.

Strings:

AAA. A ZZZ-X37

AAA 4X X9 A ZZZ-X37

AAA 4X A ZZZ-X37

RE:

^(?<g1>\s?[a-zA-Z\.]*)(?<g2>\s?[a-zA-Z\d]*)?(?<g3>\s?[a-zA-Z\d]*)?(?<g4>\s?[a-zA-Z]*)(?:\s?(?P<CAPT1>[A-Z]*)(?:-)?(?P<CAPT2>[\w\d]*)(?:-.{2})?)$

CAPT1 needs to capture the ZZZ on all the cases, but on example #1 and #3 its not getting it. I tried making the g2 and g3 group optional, but didnt seem to make a difference.

My idea now is to start matching by the end of the string, so that would capture what I need first, but if g2 and g3 could all be optional, then I would prefer it.

1 Answers

You can refactor the pattern to make the patterns inside optional groups obligatory:

^(?<g1>\s*[a-zA-Z.]+)(?<g2>\s+[a-zA-Z\d]+)?(?<g3>\s+[a-zA-Z\d]+)?(?<g4>\s?[a-zA-Z]*)(?:\s+(?P<CAPT1>[A-Z]+)-(?P<CAPT2>\w+)(?:-.{2})?)$

See the regex demo.

Basically, rather than having a chain of (x?a*)?(x?a*) etc. you can use (x+a+)?. For example, (?<g2>\s?[a-zA-Z\d]*)? turns into (?<g2>\s+[a-zA-Z\d]+)? to make sure this part is different from the one that was matched by (?<g1>\s*[a-zA-Z.]+), i.e. so that they could not match at the same location in the string.

I kept (?<g4>\s?[a-zA-Z]*) intact but if you have further issues follow the same logic, and replace it with (?<g4>\s+[a-zA-Z]+)?.

Related