diff --git a/picard/script/functions.py b/picard/script/functions.py index 7e9d97d90..10333db48 100644 --- a/picard/script/functions.py +++ b/picard/script/functions.py @@ -761,6 +761,7 @@ def func_lenmulti(parser, multi, separator=MULTI_VALUED_JOINER): """`$performer(pattern="",join=", ")` Returns the performers where the performance type (e.g. "vocal") matches `pattern`, joined by `join`. +`pattern` can be a regular expression. _Since Picard 0.10_""" )) @@ -769,7 +770,12 @@ def func_performer(parser, pattern="", join=", "): for name, value in parser.context.items(): if name.startswith("performer:"): name, performance = name.split(':', 2) - if pattern in performance: + try: + match = bool(re.search(pattern, performance)) + except re.error: + # fall back to simple string matching if regex is invalid + match = pattern in performance + if match: values.append(value) return join.join(values) diff --git a/test/test_script.py b/test/test_script.py index 4373696d8..8a3ac48da 100644 --- a/test/test_script.py +++ b/test/test_script.py @@ -3,7 +3,7 @@ # Picard, the next-generation MusicBrainz tagger # # Copyright (C) 2007 Lukáš Lalinský -# Copyright (C) 2010, 2014, 2018-2020 Philipp Wolfer +# Copyright (C) 2010, 2014, 2018-2021 Philipp Wolfer # Copyright (C) 2012 Chad Wilson # Copyright (C) 2013 Michael Wiencek # Copyright (C) 2013, 2017-2020 Laurent Monin @@ -942,6 +942,19 @@ class ScriptParserTest(PicardTestCase): self.assertEqual({'Foo1', 'Foo2', 'Foo3', 'Drummer'}, set(result.split(', '))) self.assertScriptResultEquals("$performer(perf)", "", context) + def test_cmd_performer_regex(self): + context = Metadata() + context['performer:guitar'] = 'Foo1' + context['performer:guitars'] = 'Foo2' + context['performer:rhythm-guitar'] = 'Foo3' + context['performer:drums (drum kit)'] = 'Drummer' + result = self.parser.eval(r"$performer(^guitar)", context=context) + self.assertEqual({'Foo1', 'Foo2'}, set(result.split(', '))) + result = self.parser.eval(r"$performer(^guitar\$)", context=context) + self.assertEqual({'Foo1'}, set(result.split(', '))) + result = self.parser.eval(r"$performer(drums \()", context=context) + self.assertEqual({'Drummer'}, set(result.split(', '))) + def test_cmd_performer_custom_join(self): context = Metadata() context['performer:guitar'] = 'Foo1'