2

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

Sheku Kanneh
  • 169
  • 2
  • 10

4 Answers4

3
^([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,712
  • 3
  • 17
  • 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! – Sheku Kanneh 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
  • 387,723
  • 20
  • 200
  • 263
1

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,968
  • 2
  • 22
  • 34
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
  • 1
  • 9
  • 28
  • 53