4

我正在尝试使用执行以下操作的正则表达式:匹配没有单词“Chrome”后跟单词“Safari”的任何文本

我整理了一个不起作用的python脚本。

#!/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"

我尝试了以下示例

test_negative.py "Chrome Mobile/12345 Safari"
> match

test_negative.py "Like MAC OS Safari"
> match

我希望第一个返回“不匹配”,第二个返回“匹配”。如果有人可以帮助处理正则表达式,那就太好了,谢谢。

4

3 回答 3

2

如果Safari遵循Chrome然后否定条件,你不能只写正则表达式来匹配吗?

#!/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"

这对我来说似乎更容易。

结果:

mgilson@iris:~/sandbox$ python test.py "Like MAC OS Safari" 
match
mgilson@iris:~/sandbox$ python test.py "Chrome Mobile/12345 Safari" 
no match
于 2013-05-10T15:34:48.183 回答
0

考虑以下正则表达式的 powershell 示例。此正则表达式满足您的示例,但是它确实使用了一些 python 可能不允许的外观。

  • (?<!Chrome.*?)Safari(?!.*?Chrome)|(?<!Safari.*?)Chrome(?!.*?Safari)|(?<!(Chrome|Safari).*?)$ demo'd here as Output 1. 仅当chromesafari在同一字符串上时才会失败

  • (?<!Chrome.*?)Safari|(?<!Safari.*?)$demo'd here as Output 2. 仅当chrome后面跟着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

概括

  • 输出一

    • (?<!Chrome.*?)Safari(?!.*?Chrome) 查找 Chrome 之前或之后没有的单词 Safari
    • | 或者
    • (?<!Safari.*?)Chrome(?!.*?Safari)查找单词 chrome 之前或之后没有 Safari 的单词
    • |或者
    • (?<!(Chrome|Safari).*?)$不在任何地方
  • 输出满足原始问题中确切条件的两个match any text without the word "Chrome" followed by the word "Safari"

    • (?<!Chrome.*?)Safariif Safariis 存在且不继续Chrome
    • |或者
    • (?<!Safari.*?)$safari在字符串中找不到该术语
于 2013-05-10T16:02:13.510 回答
0

这是有效的

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

>>> 
match

matcher = negative_re.search( "Chrome MAC OS Safari"  )
if matcher:
  print ("match")
else:
  print ("no match")

>>> 
no match
于 2013-05-10T16:57:10.837 回答