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

如何修改Python代码生成符合要求的音系规则符号文件?

音系规则符号提取脚本修改方案

问题描述

现有名为lts_en_us_12.9.0_phonRules_Default copy.txt的音系规则文件,内容示例如下:

word {. .} {{;}} {rewrite}
word {{#} .} {{$0} {;}} {rewrite}
word {{;} .} {{$0} {;}} {rewrite}
word {.pau .} {{$0} {;}} {rewrite}
word {. #} {{;} {$1}} {rewrite}
word {. {;}} {{;} {$1}} {rewrite}
word {. .pau} {{;} {$1}} {rewrite}
word {{;} {;}} {{;}} {rewrite}
aux-verb-reduction {{;} k aI1 n d {;} {^1 &} v {;}} {{$0} k aI1 n . d & {$8}} {optional}
aux-verb-reduction {{;} w A1 n t {;} t {u1 &} {;}} {{$0} w A1 . n & {$8}} {optional}
aux-verb-reduction {{;} l E1 t {;} m i1 {;}} {{$0} l E1 . m i {$7}} {optional}
aux-verb-reduction {{;} g I1 v {;} m i1 {;}} {{$0} g I1 . m i {$7}} {optional}

需要生成symbols.txt文件,核心要求:

  • 默认包含ε和.,固定排在顶部
  • 过滤每行开头的规则名(如word、aux-verb-reduction)和结尾的rewrite/optional,仅提取中间的左右模式内容
  • 处理$n标记:替换为对应左侧模式中索引为n的元素
  • 最终符号按字母顺序排序

现有代码未过滤无关内容、未处理$n替换、未做排序,输出不符合要求:

symbols = [("ε", 0), (".", 1)]
with open("lts_en_us_12.9.0_phonRules_Default copy.txt", "r") as f:
    for line in f:
        parts = line.strip().split(" ")
        for part in parts:
            if part not in [s[0] for s in symbols]:
                symbols.append((part, len(symbols)))

with open("symbols.txt", "w") as f:
    for symbol in symbols:
        f.write(f"{symbol[0]} {symbol[1]}\n")

修改思路

  1. 精准解析每行结构,分离规则名、左右模式和操作符,仅保留左右模式
  2. 解析模式中的元素,处理{}包裹的多元素场景
  3. 替换右模式中的$n为左模式对应索引的元素
  4. 用集合自动去重收集所有符号
  5. 按要求排序:默认符号置顶,其余按字母顺序排列
  6. 分配索引并写入目标文件

完整修改代码

import re

def parse_pattern(pattern_str):
    """解析模式字符串,提取所有元素(支持{}包裹的多元素)"""
    elements = []
    # 匹配{}包裹的内容或单个独立元素
    matches = re.findall(r'\{([^{}]+)\}|([^{}\s]+)', pattern_str)
    for match in matches:
        if match[0]:
            # 拆分{}内的多元素
            inner_elements = match[0].split()
            elements.extend(inner_elements)
        elif match[1]:
            elements.append(match[1])
    return elements

# 初始化符号集合,加入默认符号
symbol_set = {"ε", "."}

# 读取规则文件
with open("lts_en_us_12.9.0_phonRules_Default copy.txt", "r", encoding="utf-8") as f:
    for line in f:
        line = line.strip()
        if not line:
            continue
        
        # 拆分每行:规则名 左模式 右模式 操作符(不拆分{}内部的空格)
        parts = re.split(r'(?<!\{)\s(?!\})', line, maxsplit=3)
        if len(parts) < 4:
            continue
        
        _, left_pattern, right_pattern, _ = parts
        # 解析左模式元素列表
        left_elements = parse_pattern(left_pattern)
        
        # 收集左模式所有元素
        for elem in left_elements:
            symbol_set.add(elem)
        
        # 处理右模式的$n替换
        right_elements = parse_pattern(right_pattern)
        processed_right = []
        for elem in right_elements:
            if elem.startswith("$") and elem[1:].isdigit():
                idx = int(elem[1:])
                if 0 <= idx < len(left_elements):
                    processed_right.append(left_elements[idx])
            else:
                processed_right.append(elem)
        # 收集替换后的右模式元素
        for elem in processed_right:
            symbol_set.add(elem)

# 排序:默认符号置顶,其余按字母顺序排列
sorted_symbols = ["ε", "."] + sorted([s for s in symbol_set if s not in {"ε", "."}])

# 写入symbols.txt
with open("symbols.txt", "w", encoding="utf-8") as f:
    for idx, symbol in enumerate(sorted_symbols):
        f.write(f"{symbol} {idx}\n")

代码说明

  • parse_pattern函数:通过正则解析模式字符串,不管是单个元素还是{}包裹的多元素,都能准确提取
  • 符号去重:用集合存储符号,自动避免重复添加
  • 行拆分逻辑:使用正则拆分,确保不会拆分{}内部的空格,精准分离出左右模式
  • $n替换:检查右模式元素是否为$n格式,合法的索引会替换为左模式对应元素
  • 排序处理:固定ε和.在顶部,剩余符号按字母顺序排序
  • 索引分配:从0开始为每个符号分配唯一索引,写入文件

输出示例

ε 0
. 1
# 2
; 3
. # 4
. ; 5
. .pau 6
.pau . 7
; . 8
; ; 9
# . 10
# ; 11
k 12
aI1 13
n 14
d 15
^1 & 16
v 17
w 18
A1 19
t 20
u1 & 21
l 22
E1 23
m 24
i1 25
g 26
I1 27

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:05:20