我的函数以字符串hex
表示法(十六进制CSS
颜色)查找并替换为短符号。
例如:#000000
可以表示为#000
import re
def to_short_hex (string):
match = re.findall(r'#[\w\d]{6}\b', string)
for i in match:
if not re.findall(r'#' + i[1] + '{6}', i):
match.pop(match.index(i))
for i in match:
string = string.replace(i, i[:-3])
return string;
to_short_hex('text #FFFFFF text #000000 #08088')
Out:
text #FFF text #000 #08088
有没有办法使用list comprehension
等来优化我的代码。?
答案 0 :(得分:3)
这个怎么样?您可以加快将is6hexdigit
嵌入to_short_hex
,但我希望它更具可读性。
hexdigits = "0123456789abcdef"
def is6hexdigit(sub):
l = sub.lower()
return (l[0] in hexdigits) and (l.count(l[0]) == 6)
def to_short_hex(may_have_hexes):
replaced = ((sub[3:] if is6hexdigit(sub[:6]) else sub)
for sub in may_have_hexes.split('#'))
return '#'.join(replaced)
答案 1 :(得分:2)
这就是re.sub的用途!使用正则表达式查找内容然后再进行一系列搜索和替换操作来更改它并不是一个好主意。一方面,很容易意外地替换你不想要的东西,另一方面,它会做很多多余的工作。
另外,您可能希望将'#aaccee'缩短为'#ace'。这个例子也是这样做的:
def to_short_hex(s):
def shorten_match(match):
hex_string = match.group(0)
if hex_string[1::2]==hex_string[2::2]:
return '#'+hex_string[1::2]
return hex_string
return re.sub(r"#[\da-fA-F]{6}\b", shorten_match, s)
re.sub
可以使用函数来应用于每个匹配。它接收匹配对象并返回该字符串以替换该点。
切片表示法允许您应用步幅。 hex_string [1 :: 2]从字符串中获取每隔一个字符,从索引1开始并运行到字符串的结尾。 hex_string [2 :: 2]从字符串中获取每隔一个字符,从索引2开始并运行到结尾。所以对于字符串“#aaccee”,我们得到匹配的“ace”和“ace”。对于字符串“#123456”,我们得到“135”和“246”,它们不匹配。
答案 2 :(得分:1)
在迭代上使用列表上的pop
总是一个坏主意。因此,这不是优化,而是错误的纠正。另外,我修改了re
以防止识别'#34j342'
之类的字符串被接受:
>>> def to_short_hex(s):
... matches = re.findall(r'#[\dabcdefABCDEF]{6}\b', s)
... filtered = [m for m in matches if re.findall(r'#' + m[1] + '{6}', m)]
... for m in filtered:
... s = s.replace(m, m[:-3])
... return s
...
>>> to_short_hex('text #FFFFFF text #000000 #08088')
'text #FFF text #000 #08088'
此外,我认为re.search
在第二个re
中已经足够了。{/ p>