【问题标题】:Unable to find a pattern in a string using regular expression无法使用正则表达式在字符串中找到模式
【发布时间】:2021-08-12 23:05:55
【问题描述】:

我正在尝试提取CSS 代码中代表颜色的所有有效十六进制值。

十六进制颜色代码的规格

  1. 它必须以“#”符号开头。
  2. 可以有 3 位或 6 位数字。
  3. 每个数字都在 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)

当我在示例输入上运行上述代码时,它什么也没打印。 那么我在这里做错了什么?是匹配模式吗?还是我应用的逻辑?

请有人解释一下!

【问题讨论】:

  • 您的模式以^$ 为基础。所以它只会在整个字符串是单个十六进制数字时匹配,它不会在字符串中间匹配。
  • 感谢@Barmar,我已将模式更改为r'(#([A-Fa-f0-9]{3}){1,2})',现在它匹配#FfFdF8,但也匹配dF8。现在我必须做什么才能让它只匹配#FfFdF8
  • df8不以#开头时,我看不出它如何匹配。
  • 摆脱捕获组,findall() 不需要。它返回的是组而不是整个匹配。
  • 那么,我应该使用什么来代替findall() 来获得所需的输出?

标签: python css regex string hex


【解决方案1】:

去掉锚点^$,因为它们使它只匹配整个输入行。

摆脱捕获组,这样re.findall() 将只返回整个匹配项,而不是组匹配项。使用(?:...) 创建一个非捕获组,以便您可以使用{1,2} 量词。

pattern = r'#(?:[A-Fa-f0-9]{3}){1,2}'

【讨论】:

    【解决方案2】:

    你有两个或三个部分的问题:

    1. 删除 CSS cmets,它们通常包含看起来像代码的东西(可选,但推荐)
      • 匹配 cmets 的正则表达式是 /\*.*?\*/
    2. 仅查看花括号内部(例如,不查看选择器)
      • 匹配大括号的正则表达式是\{.*?\}
    3. 查找颜色代码
      • 颜色代码的正则表达式是#(?:[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
    

    注意:这可能不是一个万无一失的解决方案。为此,您需要从简单的正则表达式切换到完整的解析器。但如果你只需要快速的东西并且不介意一些边缘情况,它就足够接近了。

    【讨论】:

      猜你喜欢
      • 2021-09-15
      • 1970-01-01
      • 2015-11-28
      • 2016-08-16
      • 1970-01-01
      • 1970-01-01
      • 2019-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多