KdaiP's picture
Upload 238 files
d358e26 verified
raw
history blame
5.38 kB
import re
from .cn2an import Cn2An
from .an2cn import An2Cn
from .conf import UNIT_CN2AN
class Transform(object):
def __init__(self) -> None:
self.all_num = "零一二三四五六七八九"
self.all_unit = "".join(list(UNIT_CN2AN.keys()))
self.cn2an = Cn2An().cn2an
self.an2cn = An2Cn().an2cn
self.cn_pattern = f"负?([{self.all_num}{self.all_unit}]+点)?[{self.all_num}{self.all_unit}]+"
self.smart_cn_pattern = f"-?([0-9]+.)?[0-9]+[{self.all_unit}]+"
def transform(self, inputs: str, method: str = "cn2an") -> str:
if method == "cn2an":
inputs = inputs.replace("廿", "二十").replace("半", "0.5").replace("两", "2")
# date
inputs = re.sub(
fr"((({self.smart_cn_pattern})|({self.cn_pattern}))年)?([{self.all_num}十]+月)?([{self.all_num}十]+日)?",
lambda x: self.__sub_util(x.group(), "cn2an", "date"), inputs)
# fraction
inputs = re.sub(fr"{self.cn_pattern}分之{self.cn_pattern}",
lambda x: self.__sub_util(x.group(), "cn2an", "fraction"), inputs)
# percent
inputs = re.sub(fr"百分之{self.cn_pattern}",
lambda x: self.__sub_util(x.group(), "cn2an", "percent"), inputs)
# celsius
inputs = re.sub(fr"{self.cn_pattern}摄氏度",
lambda x: self.__sub_util(x.group(), "cn2an", "celsius"), inputs)
# number
output = re.sub(self.cn_pattern,
lambda x: self.__sub_util(x.group(), "cn2an", "number"), inputs)
elif method == "an2cn":
# date
inputs = re.sub(r"(\d{2,4}年)?(\d{1,2}月)?(\d{1,2}日)?",
lambda x: self.__sub_util(x.group(), "an2cn", "date"), inputs)
# fraction
inputs = re.sub(r"\d+/\d+",
lambda x: self.__sub_util(x.group(), "an2cn", "fraction"), inputs)
# percent
inputs = re.sub(r"-?(\d+\.)?\d+%",
lambda x: self.__sub_util(x.group(), "an2cn", "percent"), inputs)
# celsius
inputs = re.sub(r"\d+℃",
lambda x: self.__sub_util(x.group(), "an2cn", "celsius"), inputs)
# number
output = re.sub(r"-?(\d+\.)?\d+",
lambda x: self.__sub_util(x.group(), "an2cn", "number"), inputs)
else:
raise ValueError(f"error method: {method}, only support 'cn2an' and 'an2cn'!")
return output
def __sub_util(self, inputs, method: str = "cn2an", sub_mode: str = "number") -> str:
try:
if inputs:
if method == "cn2an":
if sub_mode == "date":
return re.sub(fr"(({self.smart_cn_pattern})|({self.cn_pattern}))",
lambda x: str(self.cn2an(x.group(), "smart")), inputs)
elif sub_mode == "fraction":
if inputs[0] != "百":
frac_result = re.sub(self.cn_pattern,
lambda x: str(self.cn2an(x.group(), "smart")), inputs)
numerator, denominator = frac_result.split("分之")
return f"{denominator}/{numerator}"
else:
return inputs
elif sub_mode == "percent":
return re.sub(f"(?<=百分之){self.cn_pattern}",
lambda x: str(self.cn2an(x.group(), "smart")), inputs).replace("百分之", "") + "%"
elif sub_mode == "celsius":
return re.sub(f"{self.cn_pattern}(?=摄氏度)",
lambda x: str(self.cn2an(x.group(), "smart")), inputs).replace("摄氏度", "℃")
elif sub_mode == "number":
return str(self.cn2an(inputs, "smart"))
else:
raise Exception(f"error sub_mode: {sub_mode} !")
else:
if sub_mode == "date":
inputs = re.sub(r"\d+(?=年)",
lambda x: self.an2cn(x.group(), "direct"), inputs)
return re.sub(r"\d+",
lambda x: self.an2cn(x.group(), "low"), inputs)
elif sub_mode == "fraction":
frac_result = re.sub(r"\d+", lambda x: self.an2cn(x.group(), "low"), inputs)
numerator, denominator = frac_result.split("/")
return f"{denominator}分之{numerator}"
elif sub_mode == "celsius":
return self.an2cn(inputs[:-1], "low") + "摄氏度"
elif sub_mode == "percent":
return "百分之" + self.an2cn(inputs[:-1], "low")
elif sub_mode == "number":
return self.an2cn(inputs, "low")
else:
raise Exception(f"error sub_mode: {sub_mode} !")
except Exception as e:
print(f"WARN: {e}")
return inputs