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).

Answer from Wiktor Stribiżew on Stack Overflow
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).

🌐
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

java - A regex to match a substring that isn't followed by a certain other substring - Stack Overflow
I need a regex that will match blahfooblah but not blahfoobarblah I want it to match only foo and everything around foo, as long as it isn't followed by bar. I tried using this: foo.*(? More on stackoverflow.com
🌐 stackoverflow.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 - RegExp exclusion, looking for a word not followed by another - Stack Overflow
I am trying to search for all occurrences of "Tom" which are not followed by "Thumb". I have tried to look for Tom ^((?!Thumb).)*$ but I still get the lines that match to Tom Thumb. More on stackoverflow.com
🌐 stackoverflow.com
RegEx pattern with not followed by - Stack Overflow
I want to match only first file path, which not contains word Thumbnails. I use "not-followed by pattern" but it doesn`t work. Could some one take a look and tell me where is my mistake? Here is my... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Regex Tester
regextester.com › 107904
Regex to match string NOT followed by [ - Regex Tester/Debugger
Url checker with or without http:// ... 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 ...
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.

🌐
Regular-Expressions.info
regular-expressions.info › lookaround.html
Regex Tutorial: Lookahead and Lookbehind Zero-Length Assertions
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. Inside the lookahead, we have the trivial regex u.
Find elsewhere
🌐
TutorialsTeacher
tutorialsteacher.com › regex › lookarounds
Lookarounds in Regex
The following finds any word that is not followed by a question mark ? character. ... In the above example, \b is used for a word boundary, \w+ is used for one or more word characters, so \b\w+\b finds the whole word. Pattern, \? uses escape sequence \ for ? because it is a metacharacter in regex ...
🌐
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".
🌐
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 - 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. The solutions therefore end up working a bit differently in each case. Read on to the section of this recipe for further details. ... JavaScript and Ruby 1.8 do not support lookbehind at all, even though they do support lookahead.
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<=$k;i++))
> do
> awk -v i="$i" -F "" '$i=="q" && $(i+1) !="u"  {print $0}' examplefile;done




output

prqrtwtw
ahayqlo
🌐
Notepad++ Community
community.notepad-plus-plus.org › topic › 23570 › regex-with-negative-lookahead
Regex with Negative Lookahead | Notepad++ Community
October 6, 2022 - It’s very important to unsderstand that regex engines search, BY ALL MEANS a match of the current regex against the INPUT text ... As we use the simple \R? syntax, backtracking is possible. So : First, the regex engine matches the <section class="lyrics"> part, followed with the line-break chars \r\n · But as it’s followed with the <div class="audio"> string, it does not satisfy the negative look-ahead (?!<div class="audio">)