2

我有一个像这样的模板字符串:

'%album_artist%/%album%{ (%year%)}/{%track_number%. }%track_artist% - %title%'

我想找到所有不是可选的变量,因此不被花括号括起来:track_artist, title, album_artistandalbum 但不是 track_numberand year

目前,我的表达是'(?<![{])%([A-Za-z_]+)%(?![}])',但也匹配year

为了使正则表达式不会被变量名称周围的附加字符或花括号内的多个变量混淆,我必须进行哪些更改?

我使用 Python 的re.

相关问题:

4

2 回答 2

2

如果你使用 PHP,你可以使用这个模式:

~{[^}]*+}(*SKIP)(*FAIL)|%\w++%~i

例子:

preg_match_all('~{[^}]*+}(*SKIP)(*FAIL)|%\w++%~i', $string, $matches);
print_r($matches);

如果您使用 Python,您可以使用捕获组执行相同的技巧(即:匹配大括号中的内容,然后搜索您要查找的内容):

import re

mystr = r'%album_artist%/%album%{ (%year%)}/{%track_number%. }%track_artist% - %title%';
print filter(bool, re.findall(r'{[^}]*|(?i)%(\w+)%', mystr))

注意:

您可以尝试其他模式,该模式将在% 打开大括号后最后停止匹配(不确定它是否比第一个更快):

print filter(bool, re.findall(r'{(?:[^}%]*%)*|(?i)%(\w+)%', mystr))
于 2013-10-21T19:33:28.763 回答
0

您可以尝试交替,只对与花括号不匹配的分支进行分组。它将返回带有空白字符串的结果,您可以过滤掉这些结果,例如:

>>> import re
>>> s = r'''%album_artist%/%album%{ (%year%)}/{%track_number%. }%track_artist% - %title%'''
>>> list(filter(lambda e: e.strip(), re.findall(r'\{[^}]*\}|%([^%]*)%', s)))
['album_artist', 'album', 'track_artist', 'title']
于 2013-10-22T10:07:06.987 回答