0

I'm experienced with regular expressions but new to using them in Python (Python 3 specifically). The behavior of the below script is strange to me. The goal is to match hex colors in my multiline string like #FfFdF8 but not match #BED since that's a CSS specifier.

Anyway the script is working overall, except that the number sign (#) itself isn't being included in the strings returned by findall(). So it will return, for example, "aef" instead of "#aef". I can't think what I might be overlooking, since # isn't a special regex character and findall() is supposed to return all matches as strings. Any idea?

import re

mystr = """
#BED
{
    color: #FfFdF8; background-color:#aef;
    font-size: 123px;
}
"""

lines = mystr.split('\n')

p = re.compile(r'#([a-zA-Z0-9]{3}|[a-zA-Z0-9]{6})\b')
for line in lines:
    if (line[0:4] == "    "):
        matches = p.findall(line)
        for m in matches:
            print(m)

Actual output:

FfFdF8
aef

Desired output:

#FfFdF8
#aef
Stephen
  • 6,056
  • 8
  • 40
  • 74
  • Not that it would change anything, but just for grins, have you tried escaping it? – emsimpson92 Jun 28 '18 at 22:36
  • 1
    Side note: hex colors are hexadecimal. They go from 0 to F, not to Z. – Ivar Jun 28 '18 at 22:36
  • 1
    # is also not in your capture group – emsimpson92 Jun 28 '18 at 22:37
  • @Ivar good point will fix that. – Stephen Jun 28 '18 at 22:37
  • As usual, use a non-capturing group if you want to get only matches with `re.findall`: `r'#(?:[a-zA-Z0-9]{3}|[a-zA-Z0-9]{6})\b'` – Wiktor Stribiżew Jun 28 '18 at 22:38
  • @emsimpson92 I wouldn't think it matters if it's in my capture group since findall() supposedly returns the entire match. And escaping doesn't make a difference. – Stephen Jun 28 '18 at 22:38
  • I didn't think it mattered either, but then again I've seen crazier things – emsimpson92 Jun 28 '18 at 22:40
  • @WiktorStribiżew that does actually solve this problem. But I'm confused why - isn't findall supposed to return the entire match? Why should it matter whether some subgroup is capturing or noncapturing? – Stephen Jun 28 '18 at 22:40
  • You should read the docs. Or, [read my answer](https://stackoverflow.com/a/31915134/3832970) – Wiktor Stribiżew Jun 28 '18 at 22:42
  • Oh wow, just noticed that. I had only been reading the gentler tutorial but the full part says: "If one or more groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group." I still don't fully understand the implication but that should be enough to study, thanks! – Stephen Jun 28 '18 at 22:45

0 Answers0