1

I am wondering how to build a regex that would match forever "D1B2C4Q3" but not"DDA1Q3" nor "D$1A2B".

That is a number must always follow a letter and vice versa. I've been working on this for a while and my current expression ^([A-Z0-9])(?!)+$ clearly does not work

itsthatblackkid
  • 189
  • 2
  • 11

4 Answers4

2
^([A-Z][0-9])+$

By combining the letters and digits into a single character class, the expression matches either in any order. You need to seperate the classes sequentially within a group.

Richard Woods
  • 1,918
  • 4
  • 18
  • 1
    On the same theme... `^(([A-Z][0-9]|[0-9][A-Z])+)$` Will also match a sequence beginning with a letter and alternating - not one of your test cases but implied as valid by the question. – Richard Woods Oct 10 '19 at 02:36
  • Your comment was the right solution. I should provided more details, but thank you very much! – itsthatblackkid Oct 10 '19 at 02:48
  • This answer doesn't match things like `3C4D5E`, [see the demo](https://regex101.com/r/pjjraw/1). – Tim Biegeleisen Oct 10 '19 at 02:50
  • Additionally, if you want to include sequences with odd numbers of characters, you could use: `^((\d([A-Z]\d)*[A-Z]?)|([A-Z](\d[A-Z])*\d?))$` – Richard Woods Oct 10 '19 at 02:55
1

I might actually use a simple regex pattern with a negative lookahead to prevent duplicate letters/numbers from occurring:

^(?!.*(?:[A-Z]{2,}|[0-9]{2,}))[A-Z0-9]+$

Demo

The reason I chose this approach, rather than a non lookaround one, is that we don't know a priori whether the input would start or end with a number or letter. There are actually four possible combinations of start/end, and this could make for a messy pattern.

Tim Biegeleisen
  • 451,927
  • 24
  • 239
  • 318
0

I'm guessing maybe,

^(?!.*\d{2}|.*[A-Z]{2})[A-Z0-9]+$

might work OK, or maybe not.

Demo 1

A better approach would be:

^(?:[A-Z]\d|\d[A-Z])+$

Demo 2

Or

^(?:[A-Z]\d|\d[A-Z])*$

Or

^(?:[A-Z]\d|\d[A-Z]){1,}$

which would depend if you'd like to have an empty string valid or not.

Emma
  • 26,487
  • 10
  • 35
  • 65
0

Another idea that will match A, A1, 1A, A1A, ...

^\b\d?(?:[A-Z]\d)*[A-Z]?$

See this demo at regex101

  • \b the word boundary at ^ start requires at least one char (remove, if empty string valid)
  • \d? followed by an optional digit
  • (?:[A-Z]\d)* followed by any amount of (?: upper alpha followed by digit )
  • [A-Z]?$ ending in an optional upper alpha

If you want to accept lower alphas as well, use i flag.

bobble bubble
  • 11,625
  • 2
  • 24
  • 38