如何使用负面的lookbehind

时间:2011-08-13 16:26:34

标签: python regex negative-lookbehind

基本上,我将蓝色色调的任何和所有十六进制值更改为给定样式表中的红色色调对应(即#00f更改为#ff0000(我的函数输出六个字符的十六进制值,不包括#))。

创建一个匹配十六进制颜色的正则表达式并不是一个问题(我不关心HTML颜色名称,尽管我最终关心rgbrgbahsb等值。)。这就是我最后得到的#(([0-9A-z]{3}){1,2})。它有效,但我希望它是完全证明。例如,如果有人碰巧使用具有有效十六进制值的片段(即#top)设置背景图像,我不想更改它。我尝试做一个负面的后视,但它似乎不起作用。我 使用\B#(([0-9A-z]{3}){1,2})但是如果在'#'之前有一个单词边界(例如空格),则它与URL片段匹配。这是我认为应该做的但不是:(?<!url\([^#)]*)#(([0-9A-z]{3}){1,2})

我正在使用桌面版RegExr来测试以下样式表:

body {
    background: #f09 url('images#06F');
}
span {
    background=#00f url('images#889');
}
div {
    background:#E4aaa0 url('images#889');
}
h1 {
    background: #fff #dddddd;
}

每当我将鼠标悬停在(?<!子字符串上时,RegExr会将其标识为“前方的负面外观匹配”url\([^#)]*'。“可能有一个错误,或者我只是有一个糟糕的正则表达日?虽然我们在这里,有没有其他的情况,其中'#'用于非十六进制目的?

编辑:好的,我不能在凌晨编程。该十六进制正则表达式应为#(([0-9A-Fa-f]{3}){1,2})

编辑2:好的,所以我错过了大多数语言需要静态长度观察的细节。

1 个答案:

答案 0 :(得分:0)

我认为您需要的是以下解决方案之一或其他

ss = '''    background: #f09 url('images#06F'); 
    background=#00f url('images #889'); 
    background:#E4aaa0 url('images#890'); 
    background: #fff #dddddd; '''

print ss
import re

three = '(?:[0-9A-Fa-f]{3})'

regx = re.compile('^ *background[ =:]*#(%s{1,2})' % three,re.MULTILINE)
print regx.findall(ss)

print '-----------------------------------------------------'

regx = re.compile('(?:(?:^ *background[ =:]*)|(?:(?<=#%s)|(?<=#%s%s)) +)'
                  '#(%s{1,2})' % (three,three,three,three),
                  re.MULTILINE)
print regx.findall(ss)

结果

    background: #f09 url('images#06F'); 
    background=#00f url('images #889'); 
    background:#E4aaa0 url('images#890'); 
    background: #fff #dddddd; 
['f09', '00f', 'E4aaa0', 'fff']
-----------------------------------------------------
['f09', '00f', 'E4aaa0', 'fff', 'dddddd']

编辑1

ss = '''    background: #f09 url('images#06F'); 
    background=#00f url('images #889'); 
    color:#E4aaa0 url('images#890'); 
    background: #fff #dddddd#125e88    #ae3;
    Walter (Elias) Disney: #f51f51 '''

print ss+'\n'

import re

three = '(?:[0-9A-Fa-f]{3})'

regx = re.compile('^ *[^=:]+[ =:]*#(%s{1,2})' % three,re.MULTILINE)
print regx.findall(ss)

print '-----------------------------------------------------'

regx = re.compile('(?:(?:^ *[^=:]+[ =:]*)|(?:(?<=#%s)|(?<=#%s%s)) *)'
                  '#(%s{1,2})' % (three,three,three,three),
                  re.MULTILINE)
print regx.findall(ss)

结果

    background: #f09 url('images#06F'); 
    background=#00f url('images #889'); 
    color:#E4aaa0 url('images#890'); 
    background: #fff #dddddd#125e88    #ae3;
    Walter (Elias) Disney: #f51f51 

['f09', '00f', 'E4aaa0', 'fff', 'f51f51']
-----------------------------------------------------
['f09', '00f', 'E4aaa0', 'fff', 'dddddd', '125e88', 'ae3', 'f51f51']

编辑2

ss = '''    background: #f09 url('images#06F'); 
    background=#00f url('images #889'); 
    color:#E4aaa0 url('images#890'); 
    background: #fff #dddddd#125e88    #ae3;
    Walter (Elias) Disney: #f51f51
    background: -webkit-gradient(linear, from(#000000), to(#ffffff));. '''

print ss+'\n'

import re

three = '(?:[0-9A-Fa-f]{3})'

preceding = ('(?:(?:^[^#]*)'
                 '|'
                 '(?:(?<=#%s)'
                     '|'
                     '(?<=#%s%s)'
                     '|'
                     '(?<= to\()'
                     ')'
                 ')') % (three,three,three)

regx = re.compile('%s *#(%s{1,2})' % (preceding,three), re.MULTILINE)
print regx.findall(ss)

结果

    background: #f09 url('images#06F'); 
    background=#00f url('images #889'); 
    color:#E4aaa0 url('images#890'); 
    background: #fff #dddddd#125e88    #ae3;
    Walter (Elias) Disney: #f51f51
    background: -webkit-gradient(linear, from(#000000), to(#ffffff));. 

['f09', '00f', 'E4aaa0', 'fff', 'dddddd', '125e88', 'ae3', 'f51f51', '000000', 'ffffff']

正则表达式非常强大,条件是必须有足够的字符串部分跟随某个组织,该组织在要捕获的可变其他部分之间具有相对稳定性。如果分析的文本在结构上变得过于松散,则无法编写正则表达式。

还有很多其他“丑角式拼凑”结构可用于你的琴弦吗?