如何通过Regex提取吉他tab数据并转换为对应结构DataFrame
吉他Tab文本转对应六弦DataFrame实现方案
核心实现逻辑
原始Tab文本存在[tab]前缀、末尾E弦无闭合|、带\r换行符的特征,直接单匹配e弦的规则无法覆盖6根弦的提取需求,调整后实现路径如下:
- 正则匹配规则采用
r'([eBGDAE])\|(.*?)(?:\||\r?$)',开启多行匹配模式:- 第一个捕获组匹配弦名(e/B/G/D/A/E共6根弦)
- 跳过弦名后的竖线分隔符
- 第二个捕获组提取弦上的Tab内容,匹配终止条件为下一个竖线分隔符,或行尾(兼容最后一根弦无闭合竖线的情况)
- 提取后对所有弦的内容做长度对齐,长度不足的位置补
-,保证每列对应同一演奏位置,最终按e、B、G、D、A、E的顺序生成6行的DataFrame。
可直接运行的代码实现
import re import pandas as pd # 原始抓取到的tab文本 raw_tab = """[tab]e|------------------------------------------------------------------------|\r B|----------3------5-------3----------------------------------------------|\r G|---2-4---------------4----------4-2-0-----------------------------------|\r D|---------------------------------------0---------------0-0--------------|\r A|-----------------------------------------------------2------------------|\r E|------------------------------------------------------------------------ """ # 1. 正则提取所有弦的内容 string_pattern = re.compile(r'([eBGDAE])\|(.*?)(?:\||\r?$)', re.MULTILINE) string_data = dict(string_pattern.findall(raw_tab)) # 2. 按标准弦序排序,对齐所有弦的内容长度 target_string_order = ['e', 'B', 'G', 'D', 'A', 'E'] max_length = max(len(content) for content in string_data.values()) aligned_content = [] for string_name in target_string_order: content = string_data[string_name] # 长度不足补横杠对齐 padded_content = content.ljust(max_length, '-') aligned_content.append(list(padded_content)) # 3. 生成DataFrame,每行对应一根弦 df = pd.DataFrame(aligned_content, index=target_string_order)
效果说明
生成的DataFrame共6行,索引分别对应e、B、G、D、A、E六根弦,每一列对应Tab上的一个品格位置,可直接用于后续MIDI音符转换:数字代表对应弦按压的品格数,-代表该位置弦无演奏动作。
注意:如果Tab中存在两位数的品格(比如10品、12品),可以在提取后额外做滑窗合并数字的处理,基础单数字品格的场景下上述代码可直接运行。
内容的提问来源于stack exchange,提问作者sisyphus
相关产品推荐
相关产品推荐

