You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python和弦字典含#、/特殊字符的正则匹配问题修复与优化

问题修复与代码优化方案

问题根源分析

  1. 单词边界\b失效:\b仅匹配单词字符(字母/数字/下划线)与非单词字符的边界,#属于非单词字符,导致C#被拆分为C(匹配triadeMaj)和#(被误处理)。
  2. 斜线和弦未整体匹配:原正则未考虑转位和弦(如D/F#)的结构,将其拆分为前后两部分分别匹配,导致错误拆分。
  3. 匹配顺序不合理:未按和弦长度排序,短和弦会优先匹配长和弦的前缀(如先匹配C再匹配Cmaj7,导致Cmaj7被拆分)。
  4. 代码冗余:每个和弦类型单独创建DataFrame,重复代码过多。

优化后的实现代码

import pandas as pd

# 1. 重构和弦数据:用字典统一管理所有和弦类型与对应和弦列表
chord_types = {
    'triadeMaj': ['C','C#','Db','D','D#','Eb','E','F','F#','Gb','G','G#','Ab','A','A#','Bb','B'],
    'triadeMen': ['Cm','C#m','Dbm','Dm','D#m','Ebm','Em','Fm','F#m','Gbm','Gm','G#m','Abm','Am','A#m','Bbm','Bm'],
    'triadeDim': ['Cdim','C#dim','Dbdim', 'Ddim', 'D#dim', 'Ebdim', 'Edim', 'Fdim', 'F#dim', 'Gbdim','Gdim', 'G#dim', 'Abdim', 'Adim', 'A#dim', 'Bbdim', 'Bdim'],
    'triadeAug': ['Caug','C#aug','Dbaug','Daug','D#aug','Ebaug','Eaug','Faug','F#aug','Gbaug','Gaug','G#aug','Abaug','Aaug','A#aug','Bbaug','Baug'],
    'setima': ['C7','C#7','Db7','D7','D#7','Eb7','E7','F7','F#7','Gb7','G7','G#7','Ab7','A7','A#7','Bb7','B7'],
    'setimaMen': ['Cm7','C#m7','Dbm7','Dm7','D#m7','Ebm7','Em7','Fm7','F#m7','Gbm7','Gm7','G#m7','Abm7','Am7','A#m7','Bbm7','Bm7'],
    'setimaMaj': ['Cmaj7', 'C#maj7', 'Dbmaj7', 'Dmaj7', 'D#maj7', 'Ebmaj7', 'Emaj7', 'Fmaj7', 'F#maj7','Gbmaj7','Gmaj7', 'G#maj7','Abmaj7','Amaj7','A#maj7','Bbmaj7','Bmaj7'],
    'setimaMenQui': ['Cm7b5','C#m7b5', 'Dbm7b5', 'Dm7b5', 'D#m7b5', 'Ebm7b5','Em7b5', 'Fm7b5', 'F#m7b5', 'Gbm7b5', 'Gm7b5', 'G#m7b5', 'Abm7b5', 'Am7b5', 'A#m7b5', 'Bbm7b5', 'Bm7b5'],
    'sexta': ['C6','C#6','Db6','D6','D#6','Eb6','E6','F6','F#6','Gb6','G6','G#6','Ab6','A6','A#6','Bb6','B6'],
    'sextaMen': ['Cm6','C#m6','Dbm6','Dm6','D#m6','Ebm6','Em6','Fm6','F#m6','Gbm6','Gm6','G#m6','Abm6','Am6','A#m6', 'Bbm6','Bm6']
}

# 2. 生成正则替换规则
replace_rules = {}
for type_name, chords in chord_types.items():
    # 按和弦长度降序排序,优先匹配长和弦(避免短和弦截断长和弦)
    sorted_chords = sorted(chords, key=lambda x: -len(x))
    # 用(?<!\S)/(?!\S)代替\b,兼容特殊字符;(?:/\S+)?支持匹配转位和弦的斜线部分
    pattern = fr"(?<!\S)({'|'.join(sorted_chords)})(?:/\S+)?(?!\S)"
    replace_rules[pattern] = type_name

# 3. 添加未匹配项的规则
replace_rules[r"(?<!\S)\S+(?!\S)"] = 'outros'

# 4. 应用替换(假设df是你的原始数据框)
df['chordType'] = df['chords'].replace(replace_rules, regex=True)

关键优化点说明

  1. 统一数据结构:用字典替代多个DataFrame,大幅减少重复代码,便于后续维护。
  2. 修复边界匹配:使用(?<!\S)(前面为空白/开头)和(?!\S)(后面为空白/结尾)替代\b,完美兼容带#的和弦。
  3. 支持转位和弦:通过(?:/\S+)?匹配斜线及后续的低音声部,将整个转位和弦视为一个整体匹配。
  4. 优化匹配顺序:按和弦长度降序排序,确保长和弦(如Cmaj7)优先匹配,避免被短和弦(如C)截断。

修复后结果示例

chordschordType
C#, E7, Abm, Amaj7, E, Abm, C#m, EtriadeMaj, setima, triadeMen, setimaMaj, triadeMaj, triadeMen, triadeMen, triadeMaj
E, A7, G6, D/F#, F6, E, Em, D7/F#, Fmaj7, E, A7, G6, D7/F#, F6, Em, D, Dm7, EtriadeMaj, setima, sexta, triadeMaj, sexta, triadeMaj, triadeMen, setima, setimaMaj, triadeMaj, setima, sexta, setima, sexta, triadeMen, triadeMaj, setimaMen, triadeMaj

内容的提问来源于stack exchange,提问作者PM92

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:09:21