Regex matching some and not matchin other combinations of characters

Viewed 114

I need a regex to match strings containing letters A, B or C (1), with the exception if a letter is directly preceded by a caret (e.g., A^) (2). There are no consecutive carets, but letters and numbers can come with stretches of all lengths and combinations. Ideally regex would be without lookaheads, as I'd like to use in Awk script.

43AA34C563B3545  :  no match
43A34C563^BC3545 :  no match
4334563^B3545    :  match (the only letter is after the caret)
3345664345^CCC0  :  no match
3345             :  match (no letters)

I can do #1 relatively easily with ^[^ABC]+$ but when I try to add to expand it e.g., ^[^ABC]+$|^[0-9]*\^D+[0-9]+$ it fails.

2 Answers

You might use a pattern to match digits and repeat matching ^ followed by one of [ABC] and digits

^[0-9]+(\^[ABC][0-9]+)*$

Regex demo

awk '/^[0-9]+(\^[ABC][0-9]+)*$/ {
  print $0
}

' file

Output

4334563^B3545
3345

Or a version that would also match only ^B or only digits:

^([0-9]*(\^[ABC][0-9]*)+|[0-9]+)$

Regex demo

Your matches are made of either a carat then [ABC] or a digit:

^((\^[ABC])|\d)+$

See live demo.

Replace \d with [0-9] if your regex flavour doe add by support \d (eg awk or sed).

Related