Regex: how to limit .* to only numbers & punctuation

Viewed 250

I'm trying to create statements where I can use .* with conditions (no consequtive two letters for example), and I've been failing for a while. Starting here:

"SOMETEXT 1-7, 39-41, 12B, 1-7, SOME OTHER TEXT, SOME MORE OTHER TEXT"

I want to find:

"SOMETEXT 1-7, 39-41, 12B, 1-7,"

I've made it to the point where I can look for text followed by a number and any comma:

^[A-Z]+[A-Z] [1-9].*,

using the regular expression builder here: https://regex101.com/r/yK6oF4/1

but here I still get:

"SOMETEXT 1-7, 39-41, 12B, 1-7, SOME OTHER TEXT,"

how can I tell .* to stop when it finds two consequtive letters? Or a comma, a space, and a letter? Any condition like that. I want to look only for numbers (including "numbers" such as 12B) and punctuations after what I've found before the .*.

I use R but I think this question is general about regular expressions.

1 Answers

You can use

^[A-Z]+[A-Z] [1-9].*?(?=,\s*[A-Z]{2})

See the regex demo. You can use it as stringr::str_extract(x, "^[A-Z]+[A-Z] [1-9].*?(?=,\\s*[A-Z]{2})").

Details

  • ^ - start of string
  • [A-Z]+[A-Z] - two or more uppercase letters (= [A-Z]{2,})
  • [1-9] - a digit from 1 to 9
  • .*? - any zero or more chars, other than line break chars, as few as possible
  • (?=,\s*[A-Z]{2}) - a positive lookahead that requires ,, zero or more whitespaces and then two uppercase ASCII letters immediately to the right of the current location.

In base R though, you can use

sub("^([A-Z]+[A-Z] [1-9].*?),\\s*[A-Z]{2}.*", "\\1", x, perl=TRUE)

See this regex demo.

Related