为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用正则表达式正确解析 Python 中的十六进制颜色代码?

如何使用正则表达式正确解析 Python 中的十六进制颜色代码?

守着一只汪 2022-06-28 17:55:50
我是 Regex 的初学者,所以我通过解决我能找到的所有练习来继续练习。在其中之一中,我需要使用 Regex 和 Python 从 HTML 源代码中提取所有十六进制代码。根据练习,发现十六进制代码的规则是:它以#开头它有 3 或 6 位数字每个数字都在 0-F 范围内(字符串不区分大小写)示例输入是这样的:#BED{    color: #FfFdF8; background-color:#aef;    font-size: 123px;    background: -webkit-linear-gradient(top, #f9f9f9, #fff);}#Cab{    background-color: #ABC;    border: 2px dashed #fff;}所需的输出是:#FfFdF8#aef#f9f9f9#fff#ABC#fff#BED并且#Cab将被省略,因为它们不是十六进制颜色。我尝试了这段代码,以解决问题:import retext = """#BED{    color: #FfFdF8; background-color:#aef;    font-size: 123px;    background: -webkit-linear-gradient(top, #f9f9f9, #fff);}#Cab{    background-color: #ABC;    border: 2px dashed #fff;} """r = re.compile(r'#[0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}')a = r.findall(text)print(a)获得的输出:['#BED', '#FfF', '#aef', '#f9f', '#fff', '#Cab', '#ABC', '#fff']它工作正常,除了它没有捕捉到 6 位代码并且它没有消除实际上不是十六进制颜色代码的两个标签。我误会了什么?我查看了其他尝试,但他们没有提供正确的答案。我正在使用 Python 3.7.4 和最新版本的 PyCharm。
查看完整描述

3 回答

?
森栏

TA贡献1810条经验 获得超5个赞

你可以试试

#(?:[0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})(?=;|[^(]*\))

所以这里的想法是6如果没有找到匹配字符匹配,则以更高的优先级匹配字符长度3,以确保它不匹配#BED或者我们需要匹配十六进制颜色代码的终止,所以我们使用带有交替的前瞻

//img1.sycdn.imooc.com//62bad04d0001eec405850396.jpg

查看完整回答
反对 回复 2022-06-28
?
桃花长相依

TA贡献1860条经验 获得超8个赞

您可以使用


r = re.compile(r'#[0-9A-Fa-f]{3}(?:[0-9A-Fa-f]{3})?(?!$)', re.M)

见证明


示例 Python 代码:


import re

regex = r"#[0-9A-Fa-f]{3}(?:[0-9A-Fa-f]{3})?(?!$)"

test_str = ("#BED\n"

    "{\n"

    "    color: #FfFdF8; background-color:#aef;\n"

    "    font-size: 123px;\n"

    "    background: -webkit-linear-gradient(top, #f9f9f9, #fff);\n"

    "}\n"

    "#Cab\n"

    "{\n"

    "    background-color: #ABC;\n"

    "    border: 2px dashed #fff;\n"

    "}")

matches = re.findall(regex, test_str, re.MULTILINE)

print(matches)


查看完整回答
反对 回复 2022-06-28
?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

一方面,您可以匹配 6 位代码,否则匹配 3 位代码将首先匹配其中一半(因此不匹配完整的 6 位代码)。但是,由于您还只想匹配 CSS 属性规则,而不是选择器,请提前查找;,)

(?i)#(?:[0-9a-f]{6}|[0-9a-f]{3})(?=[;,)])

https://regex101.com/r/BtZaoV/2

如果您还需要能够排除组合选择器,例如#BED, foo {,您可以先查看非{s 后跟}

(?i)#(?:[0-9a-f]{6}|[0-9a-f]{3})(?=[^{]*})

https://regex101.com/r/BtZaoV/3

使用不区分大小写的标志来保持 DRY。(您也可以{3}){1,2}用来避免重复字符集,但这会使模式更难阅读 IMO)


查看完整回答
反对 回复 2022-06-28
  • 3 回答
  • 0 关注
  • 337 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信