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
qnot followed by au. 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:
Answer from Wiktor Stribiżew on Stack OverflowIt is important to remember that a negated character class still must match a character.
q[^u]does not mean: "aqnot followed by au". It means: "aqfollowed by a character that is not au". It does not match theqin the stringIraq. It does match theqand the space after theqin Iraq is a country. Indeed: the space becomes part of the overall match, because it is the "character that is not au" that is matched by the negated character class in the above regexp. If you want the regex to match theq, and only theq, in both strings, you need to use negative lookahead:q(?!u).
java - A regex to match a substring that isn't followed by a certain other substring - Stack Overflow
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.comregex - RegExp exclusion, looking for a word not followed by another - Stack Overflow
RegEx pattern with not followed by - Stack Overflow
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
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.
I'm a RegEx Noob and I'm using the regex (i.e. not re, for all that matters) to match a string not preceded by either of two expression.
So the regex should not match
foo bar baz bar
but should match bar in
blub bar
I know how to match a string not preceded by something. That would be:
(?<!foo )bar
But I can't use
(?<!foo|baz )bar
because Python doesn't support variable width lookbehinds. From StackOverflow I learned that I could invert my string and and use a negative lookahead, but isn't there a less weird solution in my case?
oof(?! rab| zad)
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.
in addition to excellent points made by commandlineluser, you can use multiple look-behinds with re module when variable-length is required... for ex: re.search(r'(?<!foo)(?<!bigwordhere)bar', s) would be same as regex.search(r'(?<!foo|bigwordhere)bar', s)
You don't say what flavor of regex you're using, but this should work in general:
Tom(?!\s+Thumb)
In case you are not looking for whole words, you can use the following regex:
Tom(?!.*Thumb)
If there are more words to check after a wanted match, you may use
Tom(?!.*(?:Thumb|Finger|more words here))
Tom(?!.*Thumb)(?!.*Finger)(?!.*more words here)
To make . match line breaks please refer to How do I match any character across multiple lines in a regular expression?
See this regex demo
If you are looking for whole words (i.e. a whole word Tom should only be matched if there is no whole word Thumb further to the right of it), use
\bTom\b(?!.*\bThumb\b)
See another regex demo
Note that:
\b- matches a leading/trailing word boundary(?!.*Thumb)- is a negative lookahead that fails the match if there are any 0+ characters (depending on the engine including/excluding linebreak symbols) followed withThumb.
Your regexp will match file paths which do not contain "Thumbnails" right before the file extension. You want to prevent it from matching those which contain "Thumbnails" anywhere in the text.
You could try something like:
<string>((?!.*Thumbnails).*?\.jpg)</string>
Or:
<string>((?![^<]*Thumbnails)[^<]*\.jpg)</string>
(That will prevent the regexp engine from going past the closing "<" when searching for "Thumbnails". It will also disallow file paths which contain "<".)
I presume you are matching this against individual lines of text, not against a string which contains multiple lines, right?
<string>^((?!Thumbnails).)*$</string>
You can search for any line matching either of the two lines, then only look at the last one:
grep "server crashed\|server is up again" | tail -n 1
or
# Use extended regular expressions, which treat | as an operator without escaping it
grep -E "server crashed|server is up again" | tail -n 1
or
# Use egrep, a synonym for grep -E
egrep "server crashed|server is up again" | tail -n 1
If the output contains "server crashed", you need to restart the server. If the output contains "server is up again", it is still running and you needn't do anything.
I like awk for simple state machines like this
awk '
/server crashed/ {is_crashed=1}
is_crashed && /server is up again/ {is_up_again=1; exit}
END {
if (! is_up_again) {
print "Oops, crashed and NOT up again"
exit 1
}
}
' filename
Answer from The fourth bird definitely works and it is well explained as well.
As an alternative to using word boundary one can use possessive quantifier i.e. ++ to turn off backtracking thus improving efficiency further.
\$this->\w++(?!\()
RegEx Demo
Please note use of \w instead of equivalent [a-zA-Z0-9_] here.
Like a greedy quantifier, a possessive quantifier repeats the token as many times as possible. Unlike a greedy quantifier, it does not give up matches as the engine backtracks.
The (?<!\() will always be true as the character class does not match a (
Note that you don't have to escape the \_
You can use a word boundary after the character class to prevent backtracking, and turn the negative lookbehind into a negative lookahead (?!\() to assert not ( directly to the right.
\$this->[a-zA-Z0-9_]+\b(?!\()
Regex demo
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.
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

