无法使用正则表达式在字符串中找到模式
Unable to find a pattern in a string using regular expression
我正在尝试提取 CSS
代码中代表颜色的所有有效十六进制值。
十六进制色码规格
- 它必须以“#”符号开头。
- 它可以有 3 位或 6 位数字。
- 每个数字都在 0-F 或 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 满足十六进制颜色代码标准,但它们用作选择器而不是给定 CSS 中的颜色代码。
所以实际的颜色代码是
#FfFdF8
#aef
#f9f9f9
#fff
#ABC
#fff
我在 python
中尝试过的
import re
pattern = r'^#([A-Fa-f0-9]{3}){1,2}$'
n = int(input())
hexNum = []
for _ in range(n):
s = input()
if ':' in s and '#' in s:
result = re.findall(pattern,s)
if result:
hexNum.extend(result)
for num in hexNum:
print(num)
当我运行上面的示例输入代码时,它没有打印任何内容。
那么我在这里做错了什么?是匹配模式吗?还是我正在应用的逻辑?
请有人解释一下!
摆脱锚 ^
和 $
,因为它们使它只匹配整个输入行。
去掉捕获组,这样 re.findall()
只会 return 整个匹配,而不是组匹配。使用 (?:...)
创建一个非捕获组,以便您可以使用 {1,2}
量词。
pattern = r'#(?:[A-Fa-f0-9]{3}){1,2}'
你有两部分或三部分的问题:
- 删除 CSS 注释,这些注释通常包含类似代码的内容(可选,但推荐)
- 正则表达式匹配注释是
/\*.*?\*/
- 只看花括号内部(例如不看选择器)
- 匹配花括号的正则表达式是
\{.*?\}
- 查找颜色代码
- 颜色代码的正则表达式是
#(?:[A-Fa-f0-9]{3}){1,2}
综合考虑:
import re
def color_codes(css_text):
codes = []
# remove comments
css_text = re.sub(r'/\*.*?\*/', '', css_text, re.S)
# consider only {} blocks
for block in re.finditer(r'\{.*?\}', css_text, re.S):
# find color codes
codes.extend(re.findall(r'#(?:[A-Fa-f0-9]{3}){1,2}', block.group(0)))
return codes
注意:这可能不是一个万无一失的解决方案。为此,您需要从简单的正则表达式切换到完整的解析器。但如果您只需要一些快速的东西并且不介意一些边缘情况,它就足够了。
我正在尝试提取 CSS
代码中代表颜色的所有有效十六进制值。
十六进制色码规格
- 它必须以“#”符号开头。
- 它可以有 3 位或 6 位数字。
- 每个数字都在 0-F 或 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 满足十六进制颜色代码标准,但它们用作选择器而不是给定 CSS 中的颜色代码。 所以实际的颜色代码是
#FfFdF8
#aef
#f9f9f9
#fff
#ABC
#fff
我在 python
中尝试过的import re
pattern = r'^#([A-Fa-f0-9]{3}){1,2}$'
n = int(input())
hexNum = []
for _ in range(n):
s = input()
if ':' in s and '#' in s:
result = re.findall(pattern,s)
if result:
hexNum.extend(result)
for num in hexNum:
print(num)
当我运行上面的示例输入代码时,它没有打印任何内容。 那么我在这里做错了什么?是匹配模式吗?还是我正在应用的逻辑?
请有人解释一下!
摆脱锚 ^
和 $
,因为它们使它只匹配整个输入行。
去掉捕获组,这样 re.findall()
只会 return 整个匹配,而不是组匹配。使用 (?:...)
创建一个非捕获组,以便您可以使用 {1,2}
量词。
pattern = r'#(?:[A-Fa-f0-9]{3}){1,2}'
你有两部分或三部分的问题:
- 删除 CSS 注释,这些注释通常包含类似代码的内容(可选,但推荐)
- 正则表达式匹配注释是
/\*.*?\*/
- 正则表达式匹配注释是
- 只看花括号内部(例如不看选择器)
- 匹配花括号的正则表达式是
\{.*?\}
- 匹配花括号的正则表达式是
- 查找颜色代码
- 颜色代码的正则表达式是
#(?:[A-Fa-f0-9]{3}){1,2}
- 颜色代码的正则表达式是
综合考虑:
import re
def color_codes(css_text):
codes = []
# remove comments
css_text = re.sub(r'/\*.*?\*/', '', css_text, re.S)
# consider only {} blocks
for block in re.finditer(r'\{.*?\}', css_text, re.S):
# find color codes
codes.extend(re.findall(r'#(?:[A-Fa-f0-9]{3}){1,2}', block.group(0)))
return codes
注意:这可能不是一个万无一失的解决方案。为此,您需要从简单的正则表达式切换到完整的解析器。但如果您只需要一些快速的东西并且不介意一些边缘情况,它就足够了。