我有一个像这样的模板字符串:
'%album_artist%/%album%{ (%year%)}/{%track_number%. }%track_artist% - %title%'
我想找到所有不是可选的变量,因此不会被花括号括起来:track_artist
,title
,album_artist
和album
但不是 track_number
和year
。
目前,我的表达式为'(?<![{])%([A-Za-z_]+)%(?![}])'
,但也与year
匹配。
为了让正则表达式不被变量名称周围的附加字符或花括号内的多个变量混淆,我需要更改什么?
我使用Python的re
。
相关问题:
答案 0 :(得分: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))
答案 1 :(得分: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']