匹配组数目可变的正则表达式

2024-10-02 06:31:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望能够编写模式以识别列表中的文件名

import re

NOTES = ["c", "c#", "d", "d#", "e", "f", "f#", "g", "g#", "a", "a#", "b"]

filelist1 = ["piano c3.wav", "piano c#3.wav", "piano d4.wav"]
pattern1 = "piano %notename.wav"

filelist2 = ["72__54.wav", "60__127.wav", "48__61.wav"]
pattern2 = "%midinote__%velocity.wav"

关键词:

  • %midinote和{}应该是整数
  • %notename应该是列表中的字符串NOTES

以下代码可以工作并解析文件名,,但前提是模式中存在3个关键字,顺序为%midinote,%velocity,%notename:

^{2}$

但是如果一个模式:

  • 只有1或2个关键字

  • 或有3个关键字,但按之前定义的顺序排列,

然后代码失败了。在

如何能够对匹配组的变量数进行正则表达式?


Tags: 代码importre列表文件名模式关键字notes
2条回答

我想你们要找的是什么。试试这个:

pattern1 = pattern1.replace("%midinote", r"(?P<midinote>\d+)").replace("%velocity", r"(?P<velocity>\d+)").replace("%notename", r"(?P<notename>[A-Ga-g]#?[0-9])")
for fname in filelist1:
    m = re.match(pattern1, fname)
    if m:
        info = m.groupdict()
        midinote = int(info.get('midinote',0))
        velocity = int(info.get('velocity',0))
        notename = info.get('notename', 'c')
        notenametomidi = NOTES.index(notename[:-1].lower()) + (int(notename[-1])+2) * 12
        print fname, midinote, velocity, notename, notenametomidi

当然,您必须根据需要更改标准值。在

您希望使用命名的捕获组。这里有几个函数可以完成所有操作,还有一些演示代码:

# extract_midi_info.py

# For Python 2/3 compatibility
from __future__ import print_function

import re

NOTES = ("c", "c#", "d", "d#", "e", "f", "f#", "g", "g#", "a", "a#", "b")


def notename_to_midi(notename):
    return NOTES.index(notename[:-1].lower()) + (int(notename[-1])+2) * 12


def extract_midi_info(pattern, s):
    pattern = pattern.replace("%midinote", r"(?P<midinote>\d+)")
    pattern = pattern.replace("%velocity", r"(?P<velocity>\d+)")
    pattern = pattern.replace("%notename", r"(?P<notename>[A-Ga-g]#?[0-9])")

    m = re.match(pattern, s)

    if m:
        info = m.groupdict()
        if 'midinote' in info:
            info['midinote'] = int(info['midinote'])
        if 'velocity' in info:
            info['velocity'] = int(info['velocity'])
        if 'notename' in info:
            info['notename_midi'] = notename_to_midi(info['notename'])
    else:
        info = {}

    return info


def main():
    filelist_a = ["bonjour c3.wav", "bonjour c#3.wav", "bonjour d4.wav"]
    pattern_a = "bonjour %notename.wav"

    filelist_b = ["72__54.wav", "60__127.wav", "48__61.wav"]
    pattern_b = "%midinote__%velocity.wav"

    samples = [('A', filelist_a, pattern_a), ('B', filelist_b, pattern_b)]

    for name, filelist, pattern in samples:
        print()
        print('Filelist {0}'.format(name))
        for filename in filelist:
            info = extract_midi_info(pattern, filename)
            print(info)

    print()


if __name__ == '__main__':
    main()

相关问题 更多 >

    热门问题