1

Demo: https://regex101.com/r/5EVbAJ/1

I have this regexp:

a.+?(W)?.*?(\d)

My intention: get the character W as group, if the character exists in the string. Otherwise return empty group. Second group is an existing number which needs to be matched, as well.

My test data:

1. a,W1
2. a W1
3. a,W 1
4. a, V1

5. a, W1 //fail

1-3 work because there is only one character between the a and the W (I believe that's because of the lazy +? operator). 4 works because no W needs to be matched.

But 5 is not working: The number group is matched correctly, but the W group is empty, although a W occurs with 2 characters between a and W.

How can I get it fixed?

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
S-Man
  • 22,521
  • 7
  • 40
  • 63

1 Answers1

1

You may use

a(?:.+?(W))?.*?(\d)

Here, the trick is to use a non-capturing group around .+(W) pattern part to make the regex engine match this pattern at least once. This means the (W) is made an obligatory pattern, and thus Group 1 will get populated if it W is present after any 1 or more characters other than line break chars after a.

Dart test:

final regex = RegExp(r'a(?:.+?(W))?.*?(\d)');
Iterable<Match> matches = regex.allMatches("5. a, W1");
for (Match match in matches) {
    print(match.group(1)); // => W
    print(match.group(2)); // => 1
}
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • What does `?:` do? In my tests it seems to be not neccessary. – S-Man May 07 '20 at 10:43
  • @S-Man It is a [non-capturing group](https://stackoverflow.com/questions/3512471/what-is-a-non-capturing-group-in-regular-expressions), if you use a capturing one, you will end up with a redundant `.group()` in the match result. – Wiktor Stribiżew May 07 '20 at 10:45
  • Ok, yes, that works also for my much bigger regexp. But I have to think about it :D, thanks! – S-Man May 07 '20 at 10:52
  • @S-Man Please consider always posting the real patterns you are using. However, in this case, the solution is scalable enough for any pattern. – Wiktor Stribiżew May 07 '20 at 10:53