Reputation: 71
I am trying to use a regular expression which performs the following action: match any text without the word "Chrome" followed by the word "Safari"
I put together a python script that isn't working.
#!/usr/bin/env python
import sys
import re
# any text but 'Chrome' followed by Safari
negative_re = re.compile( '(?<!Chrome).*?Safari' )
matcher = negative_re.search( sys.argv[1] )
if matcher:
print "match"
else:
print "no match"
I tried the following examples
test_negative.py "Chrome Mobile/12345 Safari"
> match
test_negative.py "Like MAC OS Safari"
> match
I was hoping for the first to return "no match" and the second to return "match". If anyone could help with the regular expression, that would be great, thanks.
Upvotes: 4
Views: 606
Reputation: 26333
This is working
import sys
import re
# any text but 'Chrome' followed by Safari
negative_re = re.compile( '^(?!Chrome).*(Safari).*$' )
matcher = negative_re.search( "Void MAC OS Safari" )
if matcher:
print ("match")
else:
print ("no match")
gives
>>>
match
and
matcher = negative_re.search( "Chrome MAC OS Safari" )
if matcher:
print ("match")
else:
print ("no match")
gives
>>>
no match
Upvotes: 0
Reputation: 15000
Consider the following powershell example of regex. This regex satisfies your examples however it does use some lookarounds which might not be allowed by python.
(?<!Chrome.*?)Safari(?!.*?Chrome)|(?<!Safari.*?)Chrome(?!.*?Safari)|(?<!(Chrome|Safari).*?)$
demo'd here as Output 1. fails only if chrome
or safari
are on the same string
(?<!Chrome.*?)Safari|(?<!Safari.*?)$
demo'd here as Output 2. fails only if chrome
is followed by safari
$Matches = @()
[array]$input = @()
$input += 'Chrome Mobile/12345 Safari'
$input += 'Like MAC OS Safari'
$input += 'Safari Mobile/12345 Chrome'
$input += 'Like MAC OS chrome'
$input += 'Internet Explorer is deprecated'
$input += 'I like Chrome better then Safari for looking at kittens'
$input += 'Safari is easier to vote with'
$Regex = '(?<!Chrome.*?)Safari(?!.*?Chrome)|(?<!Safari.*?)Chrome(?!.*?Safari)|(?<!(Chrome|Safari).*?)$'
Write-Host Output 1
foreach ($String in $Input) {
if ( $String -imatch $Regex ) {
write "'$String' `t matched"
} else {
write "'$String' `t did not match"
} # end if
} # next
Write-Host
Write-Host Output 2
# but I want to allow for only:
# match any text without the word "Chrome" followed by the word "Safari"
$Regex = '(?<!Chrome.*?)Safari|(?<!Safari.*?)$'
foreach ($String in $Input) {
if ( $String -imatch $Regex ) {
write "'$String' `t matched"
} else {
write "'$String' `t did not match"
} # end if
} # next
Output 1
'Chrome Mobile/12345 Safari' did not match
'Like MAC OS Safari' matched
'Safari Mobile/12345 Chrome' did not match
'Like MAC OS chrome' matched
'Internet Explorer is deprecated' matched
'I like Chrome better then Safari for looking at kittens' did not match
'Safari is easier to vote with' matched
Output 2
'Chrome Mobile/12345 Safari' did not match
'Like MAC OS Safari' matched
'Safari Mobile/12345 Chrome' matched
'Like MAC OS chrome' matched
'Internet Explorer is deprecated' matched
'I like Chrome better then Safari for looking at kittens' did not match
'Safari is easier to vote with' matched
Output one
(?<!Chrome.*?)Safari(?!.*?Chrome)
looks for the word Safari which is not preceded or followed by Chrome|
or(?<!Safari.*?)Chrome(?!.*?Safari)
looks for the word chrome not preceded or followed by the word Safari|
or(?<!(Chrome|Safari).*?)$
not anywhere on the lineOutput two which satisfies the exact condition in the original question match any text without the word "Chrome" followed by the word "Safari"
(?<!Chrome.*?)Safari
if Safari
is exists and is not proceeded by Chrome
|
or (?<!Safari.*?)$
the term safari
is not found in the stringUpvotes: 0
Reputation: 309881
Can't you just write the regex to match if Safari follows Chrome and then negate the conditional?
#!/usr/bin/env python
import sys
import re
# any text but 'Chrome' followed by Safari
negative_re = re.compile(r'Chrome.*Safari')
matcher = negative_re.search(sys.argv[1])
if matcher is None:
print "match"
else:
print "no match"
That seems easier to me.
Results:
mgilson@iris:~/sandbox$ python test.py "Like MAC OS Safari"
match
mgilson@iris:~/sandbox$ python test.py "Chrome Mobile/12345 Safari"
no match
Upvotes: 2