My function finds in string hex notation (hexadecimal CSS colors) and replaces with the short notation.
For example: #000000 can be represented as #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
Is there any way to optimize my code using list comprehension etc..?
This is what re.sub is for! It’s not a great idea to use a regex to find something and then do a further sequence of search-and-replace operations to change it. For one thing, it’s easy to accidentally replace things you didn’t mean to, and for another it does a lot of redundant work.
Also, you might want to shorten ‘#aaccee’ to ‘#ace’. This example does that too:
Explanation
re.subcan take a function to apply to each match. It receives the match object and returns the string to substitute at that point.Slice notation allows you to apply a stride. hex_string[1::2] takes every second character from the string, starting at index 1 and running to the end of the string. hex_string[2::2] takes every second character from the string, starting at index 2 and running to the end. So for the string “#aaccee”, we get “ace” and “ace”, which match. For the string “#123456”, we get “135” and “246”, which don’t match.