How to match strings with at most n free characters between two well-defined patterns?

Viewed 43

Let's say I have the text from a bunch of articles. I want to be be able to grep for patterns related to COVID-19. How would I search for such a thing considering that some people call it Cov2, CoV-2, COVID-2, COVID19, COVID-19, COVID 19, etc...

Basically, that pattern I have so far is

grep "[Cc][Oo][Vv].{0,3}2\|[Cc][Oo][Vv].{0,3]19" file.txt

But this isn't working. I'm pretty sure the problem is the ".{0,3}" part. I'm not sure how to tell the computer to match up to 3 free characters, followed by 2 or 19, and preceded by [Cc][Oo][Vv]

1 Answers

Assuming you have a GNU grep, your pattern contains several mistakes:

  • {0,3} - in a POSIX BRE pattern, a range quantifier is defined with a pair of escaped braces, \{0,3\}
  • {0,3] - same comment, just the closing braces got replaced with ].

You can use

grep -i -E "COV.{0,3}(2|19)" file

Or, a bit more precise:

grep -i -E "COV(ID)?[-[:space:]]?(2|19)" 

See an online grep demo #1 and a demo #2.

Details

  • -i - case insensitive mode
  • -E - POSIX ERE syntax enabled (to avoid extra \ symbols in the regex pattern)
  • COV.{0,3}(2|19) - COV substring (case insensitive), then any zero to three chars, and then either 2 or 19
  • (ID)?[-[:space:]]? - matches an optional ID substring, and then an optional - or a whitespace char.
Related