1

I am doing a parser for nand2tetris project. I want to check if the destination field is either M|D|MD|A|AM|AD|AMD and their different ways of combinations like MA not only AM.

^(M|D|MD|A|AM|AD|AMD)\s*=$

This regex correctly matches AM=, but not MA=.

I don't want to list out all the possible combinations of those tokens, is there a way to do it simply?

Henok Tesfaye
  • 8,287
  • 13
  • 47
  • 84
  • I think we can list the regex matches in orders, `^(M|D|DM|A|AM|AD|ADM)\s*=7$` and also the input token in order, that will match – Henok Tesfaye Mar 07 '20 at 07:15
  • 2
    This question is likely a duplicate, but this is the regex you need `^([ADM])(?:(?!\1)([ADM])(?:(?!\1|\2)[ADM])?)?\s*=$` https://regex101.com/r/SNhJpf/2 – Nick Mar 07 '20 at 07:25
  • Thanks @Nick. Can you show the link for the duplicate and mark this question as duplicate? – Henok Tesfaye Mar 07 '20 at 07:29
  • I've been searching for it but can't find it. I seem to recall seeing something like this in the last couple of days (it was a more generic `(.)(?!\1)(.)(?!\1|\2).`) but I can't find it again. – Nick Mar 07 '20 at 07:31
  • Nick, post the answer so at least we can upvote you m8. – Athanasios Kataras Mar 07 '20 at 07:39
  • I believe [this](https://stackoverflow.com/q/13546187/9758194) is a duplicate post? If you guys are searching for one =). I believe it would boild down to `^(?!(?:.\B)*(.)(?:\B.)*\1)[AMD]+\b=$` then – JvdV Mar 07 '20 at 07:58
  • You must have been confident I would fix my answer as it was wrong at the time. :-) – Cary Swoveland Mar 07 '20 at 08:43

1 Answers1

2

This should do it:

^(?=[MDA]+$)(?!.?(.).?\1).{1,3}$

Demo

The negative lookahead attempts to match two "M"'s, two "D"'s or two "A"'s.

The positive lookahead merely restricts the characters in the string to "M", "D" and "A". That was not necessary but it allows me to use .'s in the rest, rather than (?![MDA]?([MDA])[MDA]?...), which may make it easier to read.

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100