47

I've been trying to get a specific regex working but I can't get it to do what I need.

Basically, I want it to look for ROCKET. The regex should match ROCKET in upper or lower cases, and with or without punctuation, but not when part of another word. So, the regex would trigger on any of these:

rocket
RoCKEt
hi Rocket
This is a rocket.
ROCKET's engine

but NOT trigger on ROCKET when it is found in something like

Rocketeer
Sprocket

I've been trying to get it right using a regex generator online but I can't get it to match exactly.

1
  • 2
    This is one of those [infrequent] situations where the question might be better suited for Stack Overflow. Be sure to provide a language and/or platform as each language has its own peculiarities. For example, Windows. .Net and the Regex class. (Usually, its the other way around. Stack Overflow gets hundreds of off-topic questions from developers that are better suited for Super User).
    – jww
    Apr 18, 2015 at 22:14

7 Answers 7

31

I suggest bookmarking the MSDN Regular Expression Quick Reference

you want to achieve a case insensitive match for the word "rocket" surrounded by non-alphanumeric characters. A regex that would work would be:

\W*((?i)rocket(?-i))\W*

What it will do is look for zero or more (*) non-alphanumeric (\W) characters, followed by a case insensitive version of rocket ( (?i)rocket(?-i) ), followed again by zero or more (*) non-alphanumeric characters (\W). The extra parentheses around the rocket-matching term assigns the match to a separate group. The word rocket will thus be in match group 1.

UPDATE 1: Matt said in the comment that this regex is to be used in python. Python has a slightly different syntax. To achieve the same result in python, use this regex and pass the re.IGNORECASE option to the compile or match function.

\W*(rocket)\W*

On Regex101 this can be simulated by entering "i" in the textbox next to the regex input.

UPDATE 2 Ismael has mentioned, that the regex is not quite correct, as it might match "1rocket1". He posted a much better solution, namely

(?:^|\W)rocket(?:$|\W)

20
  • 1
    Testing this out with regex testers online (regex101.com for example) shows it as invalid and not matching example strings that I enter. This is intended to be used as part of a python script. Does that make any difference in how it should be written?
    – Kefka
    Apr 18, 2015 at 19:55
  • 1
    yes it does. you can see on regex101.com that you can choose a regex "flavour" on the top left, python is slightly different. I'll update my answer with the python equivalent.
    – Xaser
    Apr 18, 2015 at 20:31
  • 1
    Thanks. I thought regexes were basically language independent.
    – Kefka
    Apr 18, 2015 at 20:33
  • 1
    They ought to be, but minor implementation differences exist.
    – Xaser
    Apr 18, 2015 at 20:36
  • 2
    And \W*(rocket)\W* matches lrocketl. It should be (?:^|\W)(rocket)(?:$|\W) (without the * and you have to check if it matches the start and/or end of the string). Apr 18, 2015 at 21:33
18

I think the look-aheads are overkill in this case, and you would be better off using word boundaries with the ignorecase option,

\brocket\b

In other words, in python:

>>> x="rocket's"
>>> y="rocket1."
>>> c=re.compile(r"\brocket\b",re.I)  # with the ignorecase option
>>> c.findall(y)
[]
>>> c.findall(x)
['rocket']
3
  • technically, non-capturing groups are no lookarounds, however the /b option yields the exact same result as Ismael's solution, but may be a little more elegant.
    – Xaser
    Apr 19, 2015 at 10:28
  • perfect solution.. covers all edge cases
    – Yitzchak
    May 10, 2021 at 7:41
  • This won't match rocket after or before an underscore, like in "_rocket", because underscore counts as \w, not \W. Feb 19 at 21:15
1

With grep and sed, you can use \<rocket\>.  With grep, the -i option will make it case-insensitive (ignore case):

grep -i '\<rocket\>'

I don't know any way to make all sed regexes case-insensitive, but there's always the caveman way:

sed -n '/\<[Rr][Oo][Cc][Kk][Ee][Tt]\>/p'
0

Use the Search for whole words only option.

As far as punctuations, you can't answer it till you know the flavour/flavor.

It's a very old thread, so posted for someone who might visit with a need, later. Ones who originated the thread might have moved to something else... No?

1
  • What is whole words only option using grep or php? Sorry, but your answer doesn't give any added value compared with other answers.
    – Toto
    Nov 23, 2019 at 11:22
0

I think you can use something like this to specific your word that you want: /^(rocket|RoCKEt)$/g

1
  • 2
    What about ROCKET?
    – Toto
    Mar 4, 2021 at 11:22
0

For online regex generators(if the text is constant):

/\brocket\b/gi

And if you need to use a variable in a regular expression, then: Ex.:

let inputStr = "I need to check the following text: rocket RoCKEt hi Rocket This is a rocket. ROCKET's engine Rocketeer Sprocket";

let replaceThis = "ROCKET";
let re = new RegExp(`\\b${replaceThis}\\b`, 'gi');
console.log(inputStr.replace(re, "******")); // "I need to check the following text: ****** ****** hi ****** This is a ******. ******'s engine Rocketeer Sprocket"
0

I don't have enough reputation to comment, so I have to make a post to share why I think the user beroe's solution is the best way to do this problem. Take for example this string of text from the codewars challenge Most frequently used words in a text:

a a a b c c d d d d e e e e e

The goal of this challenge is to count the occurrences of words in the text. If we go with the most popular solution:

(?:^|\W)rocket(?:$|\W)

in our string of text if we search for 'a' instead of 'rocket' using re.findall for python it will only return two matches (the first and last a), since the \W capture overlaps the middle a from matching. Using \b for the word barrier on the other hand returns all 3 a's as matches

\brocket\b

Agian, credit to user beroe's solution above

3

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .