Compare commits

...

5 Commits

Author SHA1 Message Date
Ella Zhang
d9ae169281
Merge 8c0cb0d691554d8311d8904972ae3efa8bfd1cc4 into b2cff0cd0abd0ac134a16ae7a9695f88e8826104 2026-06-16 22:20:28 +08:00
SapphireLab
b2cff0cd0a
fix: 多音字修改 (#2791)
* fix: 固定唑的读音

* add: 增加md5检测以更新缓存
2026-06-16 21:46:53 +08:00
Ella Zhang
8c0cb0d691
为中文添加了货币计数 2025-09-23 02:50:39 -07:00
Ella Zhang
0c02ebf5ae
Update num.py 2025-09-23 02:48:30 -07:00
Ella Zhang
82b458625d
为中文添加了货币计数 2025-09-23 02:48:07 -07:00
6 changed files with 148 additions and 5 deletions

View File

@ -10,14 +10,14 @@ import os
from text import symbols as symbols_v1
from text import symbols2 as symbols_v2
special = [
# ("%", "zh", "SP"),
("", "zh", "SP2"),
# ("¥", "zh", "SP2"), #加了货币计数所以人民币符不是SP2了
("^", "zh", "SP3"),
# ('@', 'zh', "SP4")#不搞鬼畜了,和第二版保持一致吧
]
def clean_text(text, language, version=None):
if version is None:
version = os.environ.get("version", "v2")
@ -31,6 +31,14 @@ def clean_text(text, language, version=None):
if language not in language_module_map:
language = "en"
text = " "
if language in ("zh"): #处理货币似乎最佳方案是这里截胡,不然可能被吞...
from text.zh_normalization.num import (
RE_CNY_PREFIX, RE_CNY_SUFFIX, replace_cny_prefix, replace_cny_suffix,
RE_USD_SYMBOL, RE_USD_SUFFIX, replace_usd_symbol, replace_usd_suffix,)
text = RE_CNY_PREFIX.sub(replace_cny_prefix, text)
text = RE_CNY_SUFFIX.sub(replace_cny_suffix, text)
text = RE_USD_SYMBOL.sub(replace_usd_symbol, text)
text = RE_USD_SUFFIX.sub(replace_usd_suffix, text)
for special_s, special_l, target_symbol in special:
if special_s in text and language == special_l:
return clean_special(text, language, special_s, target_symbol, version)

View File

@ -1,5 +1,6 @@
# This code is modified from https://github.com/mozillazg/pypinyin-g2pW
import hashlib
import pickle
import os
@ -14,6 +15,16 @@ current_file_path = os.path.dirname(__file__)
CACHE_PATH = os.path.join(current_file_path, "polyphonic.pickle")
PP_DICT_PATH = os.path.join(current_file_path, "polyphonic.rep")
PP_FIX_DICT_PATH = os.path.join(current_file_path, "polyphonic-fix.rep")
MD5_PATH = os.path.join(current_file_path, "polyphonic.md5")
def get_file_md5(file_path):
if not os.path.exists(file_path):
return ""
hasher = hashlib.md5()
with open(file_path, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hasher.update(chunk)
return hasher.hexdigest()
class G2PWPinyin(Pinyin):
@ -115,13 +126,22 @@ def cache_dict(polyphonic_dict, file_path):
def get_dict():
if os.path.exists(CACHE_PATH):
new_md5 = get_file_md5(PP_DICT_PATH) + get_file_md5(PP_FIX_DICT_PATH)
old_md5 = ""
if os.path.exists(MD5_PATH):
with open(MD5_PATH, "r", encoding="utf-8") as f:
old_md5 = f.read().strip()
need_rebuild = (not os.path.exists(CACHE_PATH)) or (new_md5 != old_md5)
if not need_rebuild:
with open(CACHE_PATH, "rb") as pickle_file:
polyphonic_dict = pickle.load(pickle_file)
else:
print("Rebuilding Polyphonic Dictionary: " + f"{old_md5} -> {new_md5}")
polyphonic_dict = read_dict()
cache_dict(polyphonic_dict, CACHE_PATH)
with open(MD5_PATH, "w", encoding="utf-8") as f:
f.write(new_md5)
return polyphonic_dict

View File

@ -45023,4 +45023,5 @@
鼎铛玉石: ['ding3', 'cheng1', 'yu4', 'shi2']
齿豁头童: ['chi3', 'huo1', 'tou2', 'tong2']
牦牛: ['mao2', 'niu2']
牦: ['mao2']
牦: ['mao2']
唑: ['zuo4']

View File

@ -0,0 +1 @@
13b2211c317c75794123ffdf7c2aea021c75b0c606ad61d7c8b05bb00b64fa21

View File

@ -337,3 +337,116 @@ def num2str(value_string: str) -> str:
result = result if result else ""
result += "" + verbalize_digit(decimal)
return result
RE_CNY_PREFIX = re.compile(r"(?:¥|¥)\s*(-?\d[\d,]*(?:\.\d+)?)")
RE_CNY_SUFFIX = re.compile(r"(-?\d[\d,]*(?:\.\d+)?)(?:\s*(?:人民币|元|CNY|cny|¥|¥))")
def _strip_commas(s: str) -> str:
return s.replace(",", "")
def _split_amount(amount: str):
neg = amount.startswith("-")
if neg:
amount = amount[1:]
amount = _strip_commas(amount) or "0"
if "." in amount:
integer, frac = amount.split(".", 1)
had_frac = True
else:
integer, frac, had_frac = amount, "", False
integer = integer or "0"
frac = (frac + "00")[:2]
return neg, integer, frac, had_frac
#人民币和美元的处理都在cleaner那边防吞
def replace_cny_amount(amount: str, num2str) -> str:
neg, integer, frac, had_frac = _split_amount(amount)
integer_cn = num2str(integer) if integer != "0" else ""
jiao, fen = frac[0], frac[1]
parts = []
if integer != "0":
parts.append(integer_cn + "")
else:
parts.append("零元")
if jiao != "0" or fen != "0":
if jiao != "0":
parts.append(num2str(jiao) + "")
if fen != "0":
parts.append(num2str(fen) + "")
elif had_frac:
parts.append("")
res = "".join(parts)
if neg and res and res[0] != "":
res = "" + res
return res
def replace_cny_prefix(m, num2str=num2str):
return replace_cny_amount(m.group(1), num2str)
def replace_cny_suffix(m, num2str=num2str):
return replace_cny_amount(m.group(1), num2str)
#我知道美元符也可能是加拿大元什么的但是就当它美元吧whatever
RE_USD_SYMBOL = re.compile(r"(?:\$|)\s*(-?\d[\d,]*(?:\.\d+)?)")
RE_USD_SUFFIX = re.compile(r"(-?\d[\d,]*(?:\.\d+)?)(?:\s*(?:美元|USD|usd|\$|))")
def _strip_commas(s: str) -> str:
return s.replace(",", "")
def _split_amount(amount: str):
neg = amount.startswith("-")
if neg:
amount = amount[1:]
amount = _strip_commas(amount) or "0"
if "." in amount:
integer, frac = amount.split(".", 1)
had_frac = True
else:
integer, frac, had_frac = amount, "", False
integer = integer or "0"
# 只保留两位小数用来读美分
frac = (frac + "00")[:2]
return neg, integer, frac, had_frac
def replace_usd_amount(amount: str, num2str) -> str:
neg, integer, frac, had_frac = _split_amount(amount)
integer_cn = num2str(integer) if integer != "0" else ""
jiao, fen = frac[0], frac[1]
parts = []
if integer != "0":
parts.append(integer_cn + "美元")
if jiao != "0" or fen != "0":
cents = ""
if jiao != "0":
cents += num2str(jiao) + ""
if fen != "0":
cents += num2str(fen)
cents = cents.replace("一十", "")
parts.append(cents + "美分")
elif had_frac:
parts.append("")
elif integer == "0":
parts = ["零美元"]
res = "".join(parts)
if neg and res and res[0] != "":
res = "" + res
return res
def replace_usd_symbol(m, num2str=num2str):
return replace_usd_amount(m.group(1), num2str)
def replace_usd_suffix(m, num2str=num2str):
return replace_usd_amount(m.group(1), num2str)