You don't say what flavor of regex you're using, but this should work in general:

 Tom(?!\s+Thumb)
Answer from alan on Stack Overflow
🌐
O'Reilly
oreilly.com › library › view › regular-expressions-cookbook › 9780596802837 › ch05s05.html
5.5. Find Any Word Not Followed by a Specific Word - Regular Expressions Cookbook [Book]
May 22, 2009 - You want to match any word that is not immediately followed by the word cat, ignoring any whitespace, punctuation, or other nonword characters that appear in between.
Authors   Jan GoyvaertsSteven Levithan
Published   2009
Pages   510
Discussions

regular expression - How to match a word not following a defined pattern? - Vi and Vim Stack Exchange
I have the following text file: 1: This is a book. 2: Here is the book for you. 3: There are book. 4: You can read the book. 5: Is book good to read? I want to find all occurrences of book not fol... More on vi.stackexchange.com
🌐 vi.stackexchange.com
linux - find a word/string that contains a q and not followed by a u - Unix & Linux Stack Exchange
I'm looking to find a grep command to search for all words/string that contain the letter q that is not followed by a u directly after. grep 'q!u' file More on unix.stackexchange.com
🌐 unix.stackexchange.com
Regex match pattern not preceded by either of two expressions

Are they actually the same length as foo and bar are - because it should work in that case.

>>> import re
>>> text = 'foo bar\nbaz bar\nblub bar'
>>> re.findall('\S+(?<!foo|baz) bar', text)
['blub bar']

The 3rd party regex module does support variable length (among other things)

>>> import regex as re
>>> re.findall('\S+(?<!foo|blub) bar', text)
['baz bar']

Alternative you could just capture all the matches and do the filtering yourself in code.

More on reddit.com
🌐 r/learnpython
5
5
September 17, 2019
Regex match a word not followed by two other words - Stack Overflow
I want to build a regex expression that matches the rdstation not followed by inbound OR email. More on stackoverflow.com
🌐 stackoverflow.com
May 26, 2017
Top answer
1 of 1
234

The (?!@) negative look-ahead will make word match only if @ does not appear immediately after word:

word(?!@)

If you need to fail a match when a word is followed with a character/string somewhere to the right, you may use any of the three below

word(?!.*@)       # Note this will require @ to be on the same line as word
(?s)word(?!.*@)   # (except Ruby, where you need (?m)): This will check for @ anywhere...
word(?![\s\S]*@)  # ... after word even if it is on the next line(s)

See demo

This regex matches word substring and (?!@) makes sure there is no @ right after it, and if it is there, the word is not returned as a match (i.e. the match fails).

From Regular-expressions.info:

Negative lookahead is indispensable if you want to match something not followed by something else. When explaining character classes, this tutorial explained why you cannot use a negated character class to match a q not followed by a u. Negative lookahead provides the solution: q(?!u). The negative lookahead construct is the pair of parentheses, with the opening parenthesis followed by a question mark and an exclamation point.

And on Character classes page:

It is important to remember that a negated character class still must match a character. q[^u] does not mean: "a q not followed by a u". It means: "a q followed by a character that is not a u". It does not match the q in the string Iraq. It does match the q and the space after the q in Iraq is a country. Indeed: the space becomes part of the overall match, because it is the "character that is not a u" that is matched by the negated character class in the above regexp. If you want the regex to match the q, and only the q, in both strings, you need to use negative lookahead: q(?!u).

🌐
Regex Tester
regextester.com › 107904
Regex to match string NOT followed by [ - Regex Tester/Debugger
Url checker with or without http:// or https:// Match string not containing string Check if a string only contains numbers Only letters and numbers Match elements of a url date format (yyyy-mm-dd) Url Validation Regex | Regular Expression - Taha Match an email address Validate an ip address nginx test Extract String Between Two STRINGS special characters check match whole word Match or Validate phone number Match anything enclosed by square brackets.
🌐
O'Reilly
oreilly.com › library › view › regular-expressions-cookbook › 9781449327453 › ch05s06.html
5.6. Find Any Word Not Preceded by a Specific Word - Regular Expressions Cookbook, 2nd Edition [Book]
August 27, 2012 - You want to match any word that is not immediately preceded by the word cat, ignoring any whitespace, punctuation, or other nonword characters that come between. Lookbehind lets you check if text appears before a given position. It works by instructing the regex engine to temporarily step backward in the string, checking whether something can be found ending at the position where you placed the lookbehind. See Recipe 2.16 if you need to brush up on the details of lookbehind. The following regexes use negative lookbehind, ‹(?<!⋯)›. Unfortunately, the regex flavors covered by this book differ in what kinds of patterns they allow you to place within lookbehind.
Authors   Jan GoyvaertsSteven Levithan
Published   2012
Pages   609
Top answer
1 of 2
4

The GNU grep implementation of grep that you have on Linux is able to use PCRE-style "negative look-ahead assertions". PCRE is short for "Perl compatible regular expressions". These are extensions to the standard POSIX regular expressions and the syntax for what you want to do looks like

q(?!u)

With GNU grep:

grep -P 'q(?!u)' file

would find all lines that contains a q that is not followed (directly) by a u.

Further information on lookaround assertions with PCRE may be found at, for example

  • https://www.regular-expressions.info/lookaround.html

A POSIX standard regular expression could use

q[^u]

i.e., "a q followed (directly) by something that is not a u". However, this pattern also matches the non-u character, whereas the expression with the negative look-ahead does not match the character after the q. This means that the above expression would not match a q at the end of a line, for example. To do that, you could possibly use

q([^u]|$)

which is an extended regular expression (use grep with -E for this).


As for you "word/string": A word is a string of word characters, usually characters matching [[:alpha:]]. A string is any string. The q(?!u) expression at the top would match any string that contained a q not followed (directly) by a u.

To match words containing a q but not the sequence qu, you could do either

grep -P -o -w '[[:alpha:]]*q(?!u)[[:alpha:]]*'

i.e. extract all complete words (only) that contains a q not followed by a u, or you could do it in two steps:

grep -o -w '[[:alpha:]]*q[[:alpha:]]*' | grep -v qu

This one would not require a PCRE (and hence no -P) and would get all words containing a q and then remove (with the second grep) the words that contained qu.

Example:

$ grep -o -w '[[:alpha:]]*q[[:alpha:]]*' /usr/share/dict/words  | grep -v qu
Iraq
Iraqi
Iraqian
Louiqa
miqra
nastaliq
Pontacq
q
qasida
qere
qeri
qintar
qoph
Saqib
shoq
Tareq

The PCRE variant would additionally return zaqqum as that contains a q not followed by a u.

Whichever way you do this depends on what your data looks like and what you actually want to match.

2 of 2
0

I have done by below awk command

example file

prqrtwtw
ahayqlo
prasqu

expected output

prqrtwtw
ahayqlo

command:

k=`awk -F "" '{print NF}' examplefile | sort -nr | sed -n '1p'`

for ((i=1;i<=i" -F "" '$i=="q" && $(i+1) !="u"  {print $0}' examplefile;done




output

prqrtwtw
ahayqlo
Find elsewhere
🌐
Squash
squash.io › how-to-regex-regex-not-match
Using Regular Expressions to Exclude or Negate Matches
September 12, 2023 - The string.match() function returns an array of all matches, which in this case are all the word characters that are not followed by "123" in the string "Hello123World". The pipe (|) symbol can also be used to perform a "not match" operation by specifying multiple patterns separated by the pipe symbol. This allows you to match any pattern except the ones specified. For example, the regex pattern ^(?!dog$|cat$) matches any word that is not exactly "dog" or "cat".
🌐
TutorialsTeacher
tutorialsteacher.com › regex › lookarounds
Lookarounds in Regex
In the above example, it finds a word that is preceded by the white space character. b\w+\b finds the whole word and \s is for a white space character. Negative lookbehind matches a pattern only if it is not preceded by another pattern. They are denoted by the syntax (?<!y)x, wherein it says to find x that is not preceded by y. You can think of it as a "not preceded by" pattern. ... The following finds any word that is not followed by a question mark ?
🌐
Sentry
sentry.io › sentry answers › linux › write a regular expression to match lines not containing a word
Write a regular expression to match lines not containing a word | Sentry
You can do this using a negative lookahead assertion. The PCRE regular expression below will match any line that does not contain the word “word”:
🌐
O'Reilly
oreilly.com › library › view › regular-expressions-cookbook › 9781449327453 › ch05s04.html
5.4. Find All Except a Specific Word - Regular Expressions Cookbook, 2nd Edition [Book]
August 27, 2012 - \b # Assert position at a word boundary. (?! # Not followed by: cat # Match "cat". \b # Assert position at a word boundary. ) # End the negative lookahead.
Authors   Jan GoyvaertsSteven Levithan
Published   2012
Pages   609
🌐
Medium
medium.com › @python-javascript-php-html-css › creating-patterns-to-exclude-specific-words-using-regular-expressions-0b6398c644b6
Making Patterns using Regular Expressions to Remove Particular Words | by Denis Bélanger 💎⚡✨ | Medium
August 24, 2024 - For instance, when analyzing logs, extracting data from files, or processing user input, it might be necessary to exclude lines containing specific words to meet the requirements of a given task. By using a regex pattern like ^((?!forbiddenWord).)*$, it is possible to match lines that do not contain the word “forbiddenWord”. This pattern works by asserting that at any position in the string, the specified forbidden word does not follow.
Top answer
1 of 5
194

Try:

/(?!.*bar)(?=.*foo)^(\w+)$/

Tests:

blahfooblah            # pass
blahfooblahbarfail     # fail
somethingfoo           # pass
shouldbarfooshouldfail # fail
barfoofail             # fail

Regular expression explanation

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
    .*                       any character except \n (0 or more times
                             (matching the most amount possible))
--------------------------------------------------------------------------------
    bar                      'bar'
--------------------------------------------------------------------------------
  )                        end of look-ahead
--------------------------------------------------------------------------------
  (?=                      look ahead to see if there is:
--------------------------------------------------------------------------------
    .*                       any character except \n (0 or more times
                             (matching the most amount possible))
--------------------------------------------------------------------------------
    foo                      'foo'
--------------------------------------------------------------------------------
  )                        end of look-ahead
--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    \w+                      word characters (a-z, A-Z, 0-9, _) (1 or
                             more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
  )                        end of \1
--------------------------------------------------------------------------------
  $                        before an optional \n, and the end of the
                           string

Other regex

If you only want to exclude bar when it is directly after foo, you can use

/(?!.*foobar)(?=.*foo)^(\w+)$/

Edit

You made an update to your question to make it specific.

/(?=.*foo(?!bar))^(\w+)$/

New tests

fooshouldbarpass               # pass
butnotfoobarfail               # fail
fooshouldpassevenwithfoobar    # pass
nofuuhere                      # fail

New explanation

(?=.*foo(?!bar)) ensures a foo is found but is not followed directly bar

2 of 5
64

To match a foo following by something that doesn't start with bar, try

foo(?!bar)

Your version with negative lookbehind is effectively "match a foo followed by something that doesn't end in bar". The .* matches all of barblah, and the (?<!bar) looks back at lah and checks that it doesn't match bar, which it doesn't, so the whole pattern matches.

🌐
Wyssmann Engineering
wyssmann.com › adrian's tech kb & blog › blog › regular expression ignore or exclude a specific word, find everything else
Regular Expression - ignore or exclude a specific word, find everything else | Adrian's Tech KB & Blog
March 24, 2021 - Similar to positive lookahead, except that negative lookahead only succeeds if the regex inside the lookahead fails to match. So the final solution using the techniques mentioned above · \b asserts the position at a word boundary · (?! not followed by · None the word we want to “ignore” i.e.
🌐
Baeldung
baeldung.com › home › algorithms › searching › regular expression to match text without a certain word
Regular Expression to Match Text Without a Certain Word | Baeldung on Computer Science
March 18, 2024 - If it fails to match, the single character “” (following the negative lookahead group) tells us to add the first character of to the matching result and to increase the search pointer by one. Otherwise, we terminate the method and return false. The metacharacter following the sub-pattern is the greedy quantifier , which tells us to keep repeating the previous steps until we reach the end of the text (hence, the dollar sign at the end of the regular expression). ... Let’s work out an example. Our search word is “founder”, and our English text is as follows: