1

I want to parse chord names using regular expressions in python. The following code matches only chords like G#m

chord_regex = "(?P<chord>[A-G])(?P<accidental>#|b)?(?P<additional>m?)"

How am I able to also match chords with the shape Gm#? Can the above regex be altered to also match these types of chords?

anopheles
  • 434
  • 1
  • 9
  • 19
  • Have a look at http://stackoverflow.com/questions/11229080/regex-for-matching-a-music-chord – Fredrik Pihl Mar 10 '13 at 19:11
  • http://stackoverflow.com/questions/11229597/music-chord-regex and http://regexadvice.com/forums/thread/20327.aspx – Fredrik Pihl Mar 10 '13 at 19:12
  • Thanks, but none of the link answer my question. I have a very specific question, i.e. how do I change the above regexp to cover both cases. I'm not looking for a regexp to parse arbitrary chords, e.g. Cmaj7 or G#add9. – anopheles Mar 10 '13 at 19:25
  • Surely `Gm#` is not a valid chord? It's not the `m` that's sharp, it's the `G`. – Daniel Roseman Mar 10 '13 at 19:38
  • @DanielRoseman: I'm well aware of that. Unfortunately, I don't have control over the input I receive, i.e. I also have to handle these special cases which are indeed false chords. – anopheles Mar 10 '13 at 19:54

1 Answers1

2

You should use the {m,n} syntax to specify m=0 to n=2 matches of a group (where said group is either the accidental or additional), like so:

>>> import re
>>> regex = "(?P<chord>[A-G])((?P<accidental>#|b)|(?P<additional>m)){0,2}"
>>> re.match(regex, "Gm").groupdict()
{'chord': 'G', 'additional': 'm', 'accidental': None}
>>> re.match(regex, "G").groupdict()
{'chord': 'G', 'additional': None, 'accidental': None}
>>> re.match(regex, "G#m").groupdict()
{'chord': 'G', 'additional': 'm', 'accidental': '#'}
>>> re.match(regex, "Gm#").groupdict()
{'chord': 'G', 'additional': 'm', 'accidental': '#'}
tom
  • 18,953
  • 4
  • 35
  • 35