WeTextProcessing 0.1.12__py3-none-any.whl → 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. {WeTextProcessing-0.1.12.dist-info → WeTextProcessing-0.2.1.dist-info}/METADATA +1 -1
  2. WeTextProcessing-0.2.1.dist-info/RECORD +114 -0
  3. {WeTextProcessing-0.1.12.dist-info → WeTextProcessing-0.2.1.dist-info}/WHEEL +1 -1
  4. itn/chinese/rules/cardinal.py +2 -1
  5. itn/chinese/rules/license_plate.py +4 -1
  6. itn/zh_itn_tagger.fst +0 -0
  7. tn/chinese/rules/cardinal.py +4 -2
  8. tn/chinese/rules/math.py +14 -5
  9. tn/chinese/rules/measure.py +1 -4
  10. tn/en_tn_tagger.fst +0 -0
  11. tn/en_tn_verbalizer.fst +0 -0
  12. tn/english/__init__.py +0 -0
  13. tn/english/data/__init__.py +0 -0
  14. tn/english/data/address/__init__.py +13 -0
  15. tn/english/data/date/__init__.py +0 -0
  16. tn/english/data/electronic/__init__.py +0 -0
  17. tn/english/data/measure/__init__.py +13 -0
  18. tn/english/data/money/__init__.py +0 -0
  19. tn/english/data/number/__init__.py +13 -0
  20. tn/english/data/ordinal/__init__.py +0 -0
  21. tn/english/data/roman/__init__.py +0 -0
  22. tn/english/data/telephone/__init__.py +0 -0
  23. tn/english/data/time/__init__.py +13 -0
  24. tn/english/data/whitelist/__init__.py +0 -0
  25. tn/english/normalizer.py +92 -0
  26. tn/english/rules/__init__.py +0 -0
  27. tn/english/rules/cardinal.py +186 -0
  28. tn/english/rules/date.py +319 -0
  29. tn/english/rules/decimal.py +194 -0
  30. tn/english/rules/electronic.py +213 -0
  31. tn/english/rules/fraction.py +139 -0
  32. tn/english/rules/measure.py +327 -0
  33. tn/english/rules/money.py +124 -0
  34. tn/english/rules/ordinal.py +96 -0
  35. tn/english/rules/punctuation.py +81 -0
  36. tn/english/rules/roman.py +149 -0
  37. tn/english/rules/telephone.py +180 -0
  38. tn/english/rules/time.py +167 -0
  39. tn/english/rules/whitelist.py +153 -0
  40. tn/english/rules/word.py +59 -0
  41. tn/english/test/__init__.py +0 -0
  42. tn/english/test/cardinal_test.py +28 -0
  43. tn/english/test/date_test.py +28 -0
  44. tn/english/test/decimal_test.py +28 -0
  45. tn/english/test/electronic_test.py +28 -0
  46. tn/english/test/fraction_test.py +28 -0
  47. tn/english/test/measure_test.py +28 -0
  48. tn/english/test/money_test.py +28 -0
  49. tn/english/test/normalizer_test.py +28 -0
  50. tn/english/test/ordinal_test.py +28 -0
  51. tn/english/test/roman_test.py +28 -0
  52. tn/english/test/telephone_test.py +28 -0
  53. tn/english/test/time_test.py +28 -0
  54. tn/english/test/utils.py +32 -0
  55. tn/english/test/whitelist_test.py +28 -0
  56. tn/english/test/word_test.py +28 -0
  57. tn/main.py +22 -11
  58. tn/processor.py +17 -1
  59. tn/token_parser.py +11 -2
  60. tn/utils.py +92 -0
  61. tn/zh_tn_tagger.fst +0 -0
  62. WeTextProcessing-0.1.12.dist-info/RECORD +0 -66
  63. {WeTextProcessing-0.1.12.dist-info → WeTextProcessing-0.2.1.dist-info}/LICENSE +0 -0
  64. {WeTextProcessing-0.1.12.dist-info → WeTextProcessing-0.2.1.dist-info}/entry_points.txt +0 -0
  65. {WeTextProcessing-0.1.12.dist-info → WeTextProcessing-0.2.1.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: WeTextProcessing
3
- Version: 0.1.12
3
+ Version: 0.2.1
4
4
  Summary: WeTextProcessing, including TN & ITN
5
5
  Home-page: https://github.com/wenet-e2e/WeTextProcessing
6
6
  Author: Zhendong Peng, Xingchen Song
@@ -0,0 +1,114 @@
1
+ itn/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ itn/__main__.py,sha256=jFh8bEB_lC5y7ab9VMqAxWRaI8D-SpBSTiHfMJC1b10,65
3
+ itn/main.py,sha256=NnT9Sh3VTEI0sX_DO9IGVsXCWtZyfRbzj9Sj_6cBxqM,2610
4
+ itn/zh_itn_tagger.fst,sha256=vRgLHTqqchvubK6kKt8_fHhbxRfBykCbLQfhFMk_I64,1080610
5
+ itn/zh_itn_verbalizer.fst,sha256=pHXRUfzls2UmWwTmHHhYmBWMusIfWpU3I7IwxeRjn28,119018
6
+ itn/chinese/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ itn/chinese/inverse_normalizer.py,sha256=HCNW5WCHEYeu60f8lxRmvpXh_48GcXa036EFFR9PQo0,3560
8
+ itn/chinese/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ itn/chinese/rules/cardinal.py,sha256=x3pBfnqzWr85BMkYSOJ87IPL_vAqrCGrUDJvugbq5ZY,7385
10
+ itn/chinese/rules/char.py,sha256=wWnTfzJqE5j7kvEao9rKSN29OVFGNnL25MxS7PcfWEM,965
11
+ itn/chinese/rules/date.py,sha256=dA_AQTXaKfO9U8Mtp-ZT9bYdsaOhp5GHC1UpArNm5DY,2319
12
+ itn/chinese/rules/fraction.py,sha256=cYfBcV3XrXo7SIKFOfvOKjFITnhqxJkyiEaU8byiI8A,1966
13
+ itn/chinese/rules/license_plate.py,sha256=DX9JJjQhh8L6G_8fkVWuabABtw5wjFwQdfS3zxili6M,1439
14
+ itn/chinese/rules/math.py,sha256=WmcZQdns7pY4v5gQajEacnHbedP3w_KJVn3WUvoeZkE,1199
15
+ itn/chinese/rules/measure.py,sha256=JJSdhporTtcXg5wQ4VSqcYlUCx58UOSuWvmOPMHiges,2985
16
+ itn/chinese/rules/money.py,sha256=lNixki_73PNefQUECRUYebmD461klNXTtKQm61o4Nu8,2160
17
+ itn/chinese/rules/postprocessor.py,sha256=Eq9aZc7T5OkZGQB15r2qeT8SblS5cvnEosqHjLTN8To,1144
18
+ itn/chinese/rules/time.py,sha256=4sX_3_lhnjQh0fkEBnP7rGnoTPbquHDXaV5lbeGW75M,1931
19
+ itn/chinese/rules/whitelist.py,sha256=UuvIORHZiezfAKWK7qL3QByTGxHMXVnOZp-lYrwmewk,1081
20
+ itn/chinese/test/__init__.py,sha256=eOXRztjSZS0xmUruH2eKjdHx6RtmMxBtae5aFxKrgaE,605
21
+ itn/chinese/test/normalizer_test.py,sha256=a9nqt-is07zYOl3XDAhjUyNzBlwBe3qdaHtvTT6dWn4,4832
22
+ itn/chinese/test/utils.py,sha256=aCZH5BL0dghGjemhVwfISBUxLFMG_ceMzwzuOb5ht28,1094
23
+ tn/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ tn/__main__.py,sha256=OUMsgyp8SWb7raJY_py61uM29j023yE5po95O9yinzk,64
25
+ tn/en_tn_tagger.fst,sha256=0HNXORdRchR_5vVqnNZ2uUnF4NttdDakHSEHwqRwquQ,4224622
26
+ tn/en_tn_verbalizer.fst,sha256=9-fNlryvn5J_1IOsylqd4Bsdj3oqlL0qDiNYHPoD9Us,1683542
27
+ tn/main.py,sha256=Q45id3b2g71MPRLnaHpo8iWPc38MeyZKigNd5FinNvI,3578
28
+ tn/processor.py,sha256=aAcHF3mwyhbPDAwxZKD6tPho-xL6ZNJMrHuw5e7TaQo,4258
29
+ tn/token_parser.py,sha256=nsTYzug-gq2HYnTJHja_HXntoRVX3gITQAlI9z8WvWU,4487
30
+ tn/utils.py,sha256=lJLuW2jkobgXCyNYl29zhtyb3B80CS7Pqz7zqHRVr4c,2792
31
+ tn/zh_tn_tagger.fst,sha256=zZ7zLr-Y774X3lb9bnmUv9Fs3Gv-LXa44X0rMFL6a9g,3477714
32
+ tn/zh_tn_verbalizer.fst,sha256=VoZnjew7YiDRoDC6TgDHKXhrkcSGOz030Pnqad8JhcE,558366
33
+ tn/chinese/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ tn/chinese/normalizer.py,sha256=kCeK1Ab-58RVfpcNsvj_TL9mClsPFjTgjLnOxWFKbAI,3848
35
+ tn/chinese/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ tn/chinese/rules/cardinal.py,sha256=qPX9phKDlOctzKjwrru9kBprzb6rE6wyvj3WmHhID4E,3611
37
+ tn/chinese/rules/char.py,sha256=wWnTfzJqE5j7kvEao9rKSN29OVFGNnL25MxS7PcfWEM,965
38
+ tn/chinese/rules/date.py,sha256=Q1uqPOGSB6UJcrBY3ERs-gj_Caq9yA6Uxmk1NTfzmZo,2382
39
+ tn/chinese/rules/fraction.py,sha256=8K7YQp-QWXJI6iOswMS1PSf6-ocBnLOKiqzv8FIWHfc,1520
40
+ tn/chinese/rules/math.py,sha256=PB62l3LT9Y6LqURfE3driJHrDTmdxtPHSBSxwzpl3t0,1547
41
+ tn/chinese/rules/measure.py,sha256=pjkIzWRi2YxzDlkJoGtqde7vl5foCJ7xjvW70pHZTYs,2802
42
+ tn/chinese/rules/money.py,sha256=Bu9rNGIBP3QvbceyS4_NrHPfcFISf70vtoffiV_Ahuc,1567
43
+ tn/chinese/rules/postprocessor.py,sha256=a3wA2Aqg-MtyT-it_bqdj9_oJ2bG47gfzKwaL7dgXpk,2100
44
+ tn/chinese/rules/preprocessor.py,sha256=5pQ98OlMFxf8V3C74dTQc0uWeKUhZLA3jNVi61Z4fOA,1092
45
+ tn/chinese/rules/sport.py,sha256=6NSWEiJhSX3aymY5263JDgZkdUZP8BYdJFAc8l51R1c,1726
46
+ tn/chinese/rules/time.py,sha256=mfdAb7whCc0li6cDQKIwi10xcaM7EIjfI8mK7lIFyYQ,2047
47
+ tn/chinese/rules/whitelist.py,sha256=JzrL-UfedP7FSps5s4xhSjfEcCkVKzEEGdkZfE96i2E,1652
48
+ tn/chinese/test/__init__.py,sha256=eOXRztjSZS0xmUruH2eKjdHx6RtmMxBtae5aFxKrgaE,605
49
+ tn/chinese/test/cardinal_test.py,sha256=o0LVTOMNMIgwADl7wYHRBBH6s2fLli9kU5BaYxdIHBc,1246
50
+ tn/chinese/test/char_test.py,sha256=p4vG0iwc2FYn0uTbQQzWBq-TLgfIWMfgKqfu1vpP50o,954
51
+ tn/chinese/test/date_test.py,sha256=TEF8wYGl1Ubr_5daSnp92cJY2yCPv81aZ9j3BfA8osU,954
52
+ tn/chinese/test/fraction_test.py,sha256=w2Pa7yiHG85TbU8XWf-ZDbB49g52bI1pDOEZUdMxVnE,994
53
+ tn/chinese/test/math_test.py,sha256=w__bpbDFK4VsGK-fWenHfV9Y_SImBb6q9g-twplbqGc,954
54
+ tn/chinese/test/measure_test.py,sha256=k76Dz32DXvl6bBjbceISH4Xiz6xAhBwJRv3OYCvp0OE,982
55
+ tn/chinese/test/money_test.py,sha256=MrQQTJQHPql1mNIOljomlLyqIm-MS5xlvyIGT7KaboU,964
56
+ tn/chinese/test/normalizer_test.py,sha256=rRf9xpGpnhAICwnAhcMqOg5RSvJUxvSc5qy2U5kM1ak,1597
57
+ tn/chinese/test/postprocessor_test.py,sha256=KNXdVJQ3AyCsPqjiiFxk9QQoALUDRcSDvzsLa2OGxd4,1099
58
+ tn/chinese/test/preprocessor_test.py,sha256=ipNvTn0MYcR0MDyOQuT_hR8DKiDHWoYZb4coANX31Kk,1082
59
+ tn/chinese/test/sport_test.py,sha256=ZF4QpgbfIZ38bwnCE5a9gkR1jv1N6RvN4VECHQImOl8,964
60
+ tn/chinese/test/time_test.py,sha256=hLi3gCwVrV4oOdStWCwOeT6c9XTOatjOB8pFfbe6r0I,953
61
+ tn/chinese/test/token_parser_test.py,sha256=8JcSqlvaYTZ46rZgMsfAVNmcYez6t0gonhnx4nc-1ew,2614
62
+ tn/chinese/test/utils.py,sha256=aCZH5BL0dghGjemhVwfISBUxLFMG_ceMzwzuOb5ht28,1094
63
+ tn/chinese/test/whitelist_test.py,sha256=oPB-7_g8l6zhAeH5fp7NlaRJYcDNz7VAOKwhCnebGdc,1003
64
+ tn/english/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
+ tn/english/normalizer.py,sha256=vC5GwQkHpiSSwF-ASzBBWfk3t4Xccslkez4yP93Mp90,3777
66
+ tn/english/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
+ tn/english/data/address/__init__.py,sha256=EqFAHHjK7kJqR_FV8vBLddBJWhbVD8pREEfm8C5nSEE,623
68
+ tn/english/data/date/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
+ tn/english/data/electronic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
+ tn/english/data/measure/__init__.py,sha256=TS5NMVLZXlTIgbt7grYmlxBfRKrWELPnT9DedX9kYBk,610
71
+ tn/english/data/money/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
+ tn/english/data/number/__init__.py,sha256=TS5NMVLZXlTIgbt7grYmlxBfRKrWELPnT9DedX9kYBk,610
73
+ tn/english/data/ordinal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
+ tn/english/data/roman/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
+ tn/english/data/telephone/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
+ tn/english/data/time/__init__.py,sha256=TS5NMVLZXlTIgbt7grYmlxBfRKrWELPnT9DedX9kYBk,610
77
+ tn/english/data/whitelist/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
+ tn/english/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
+ tn/english/rules/cardinal.py,sha256=w3HvKbq86mZjb3MhXc96D_Ajaem1raCHs0pCGvhQaRs,8424
80
+ tn/english/rules/date.py,sha256=QoUczkPwAeYanT41_8Qpi_FqvuSfvXX5LHdEgcsLkVA,13683
81
+ tn/english/rules/decimal.py,sha256=s49eTpngiE4BZyLvfgsg45kpcemElWTLGx7VuxVR1Rw,8795
82
+ tn/english/rules/electronic.py,sha256=2XBnz3usFyFame2WcInVrtZEW5TPXXowANpLeBEjD7I,9190
83
+ tn/english/rules/fraction.py,sha256=ltGhbd1Qeb-BsuVCPYq8cc__k0Xkkn4WBUiz6dFs8J8,5685
84
+ tn/english/rules/measure.py,sha256=DjQnq_9UXL-pHdqaHkp3oUv4qEhiGB_764YmUEq9v6w,14025
85
+ tn/english/rules/money.py,sha256=0hjQWUdI4wWsOVKkkBs5lvFsQaMIWOQcs6oOLBhQzDM,5457
86
+ tn/english/rules/ordinal.py,sha256=xFUaNvPx2rKDJz3TMiE2RKje6gcvcVImr3sXixWfOKU,3989
87
+ tn/english/rules/punctuation.py,sha256=KyypaQs7SsQC1RCv-h4NGu4Jm-PvuSGUyM3mtPbCMws,2979
88
+ tn/english/rules/roman.py,sha256=pQFuSIjzWnMN-jiSuVqv3AxJEA9kA8s0NUgGpCCVbiU,6051
89
+ tn/english/rules/telephone.py,sha256=JkhHZU1O2h4a_W3QHVBY1lOQvq4Tys5JwAlL1Kkt8Pg,8275
90
+ tn/english/rules/time.py,sha256=7quSQrLifeJ4WLwAyDkuvGe1-lNomN_MjvFAP3zHBas,7764
91
+ tn/english/rules/whitelist.py,sha256=5pIEZyCadKmS7AAJ7G7JQhWFvo2oPszy0WxxIAMZr_E,6097
92
+ tn/english/rules/word.py,sha256=ySAa3qn6Wf1Qze9limjPfYJd37Kk2Juz9AZseGEFNu8,2366
93
+ tn/english/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
+ tn/english/test/cardinal_test.py,sha256=F7vP5ZIOxoQhRJ0Se597bHinRnFU_bOd2PzTo9M0xmg,1013
95
+ tn/english/test/date_test.py,sha256=dFOJXAdU19i3i7KZdt89PQ-c0EeGmjUhQCXT8bFE71o,973
96
+ tn/english/test/decimal_test.py,sha256=28Q4YCEPGRoQ-6s3zroyxUbVZ2GiALxZXjXmQcs9WwQ,1003
97
+ tn/english/test/electronic_test.py,sha256=iWgt4lFHDfrZZLyBAMSL5AOjATeFK1CrUDLLWUMll8I,1033
98
+ tn/english/test/fraction_test.py,sha256=aQrDwqjjfDN0CWM34VOOTINfos0MHzuY6Cjhv7cF9jE,1013
99
+ tn/english/test/measure_test.py,sha256=14dGDfjdbYiH0MYBmPD9JvfVAXW_-Fe4rPCrWJ72T-A,1003
100
+ tn/english/test/money_test.py,sha256=oVhT7JpTaTekOPuMLmaubSv5912ow35OsPquikULi2A,983
101
+ tn/english/test/normalizer_test.py,sha256=wNq2SE2DyGmDQQ4D1yFrYszE8czFvGOlvKwsCX2ymKQ,1006
102
+ tn/english/test/ordinal_test.py,sha256=sqrPIy9ZABNSKQaadU-GfYydnh3dUxk2SfkjlZfHfp4,1003
103
+ tn/english/test/roman_test.py,sha256=Lemo7K4I-EoJ34yeT9VVLTHOSOYVzpK3xnCQ38Fer5w,983
104
+ tn/english/test/telephone_test.py,sha256=I9xnKNXfWagRTHS8hvBvJKAqeFvH8_sjD5G3n8pEwys,1023
105
+ tn/english/test/time_test.py,sha256=4E_PS-D5caTUZgrI-UL7q0aoqmtD8np7yeXUkGyc1Qo,973
106
+ tn/english/test/utils.py,sha256=aCZH5BL0dghGjemhVwfISBUxLFMG_ceMzwzuOb5ht28,1094
107
+ tn/english/test/whitelist_test.py,sha256=fnlpnwiDgQWsl5ONZklWXEyLQoUSuwhdowcV7a8fXvw,1023
108
+ tn/english/test/word_test.py,sha256=ACguloXPl4Ttw8fj9F_wvr1coaQAoj_MLOJ74wyy-WY,954
109
+ WeTextProcessing-0.2.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
110
+ WeTextProcessing-0.2.1.dist-info/METADATA,sha256=pbmZTrV2ciHEHe7DO_JPIk0pxxJQ_xD1VzZehI7WN7Q,5178
111
+ WeTextProcessing-0.2.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
112
+ WeTextProcessing-0.2.1.dist-info/entry_points.txt,sha256=iAd8tFSNA8AY5fUECPlk9KaDFC3ISvDjoKAZVsCWPjE,61
113
+ WeTextProcessing-0.2.1.dist-info/top_level.txt,sha256=6NasE_UheQezX9_0V3MbiOSnTQpvM_funMjv4wpMGgA,7
114
+ WeTextProcessing-0.2.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: bdist_wheel (0.43.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -134,8 +134,9 @@ class Cardinal(Processor):
134
134
  cardinal |= (number + dot + digits.plus)
135
135
  # cardinal string like 110 or 12306 or 13125617878, used in phone,
136
136
  # 340621199806051223, used in ID card
137
+ idcard_last_char = digits | 'X' | 'x'
137
138
  cardinal |= (digits**3 | digits**4 | digits**5 | digits**11
138
- | digits**18)
139
+ | (digits**17 + idcard_last_char) | digits**18)
139
140
 
140
141
  # 4. 特殊格式的数字 + 标准数字
141
142
  # cardinal string like 23
@@ -27,8 +27,11 @@ class LicensePlate(Processor):
27
27
 
28
28
  def build_tagger(self):
29
29
  digit = string_file('itn/chinese/data/number/digit.tsv') # 1 ~ 9
30
+ zero = string_file('itn/chinese/data/number/zero.tsv') # 0
31
+ digits = zero | digit
30
32
  province = string_file(
31
33
  'itn/chinese/data/license_plate/province.tsv') # 皖
32
- license_plate = province + self.ALPHA + (self.ALPHA | digit)**5
34
+ license_plate = province + self.ALPHA + (self.ALPHA | digits)**5
35
+ license_plate |= province + self.ALPHA + (self.ALPHA | digits)**6
33
36
  tagger = insert('value: "') + license_plate + insert('"')
34
37
  self.tagger = self.add_tokens(tagger)
itn/zh_itn_tagger.fst CHANGED
Binary file
@@ -64,11 +64,13 @@ class Cardinal(Processor):
64
64
  number @= self.build_rule(
65
65
  cross('二百', '两百')
66
66
  | cross('二千', '两千')
67
- | cross('二万', '两万'))
68
- self.number = accep('约').ques + accep('人均').ques + number.optimize()
67
+ | cross('二万', '两万')).optimize()
68
+ percent = insert('百分之') + number + delete('%')
69
+ self.number = accep('约').ques + accep('人均').ques + (number | percent)
69
70
 
70
71
  # cardinal string like 127.0.0.1, used in ID, IP, etc.
71
72
  cardinal = digits.plus + (dot + digits.plus)**3
73
+ cardinal |= percent
72
74
  # xxxx-xxx-xxx
73
75
  cardinal |= digits.plus + (delete('-') + digits.plus)**2
74
76
  # xxx-xxxxxxxx
tn/chinese/rules/math.py CHANGED
@@ -15,23 +15,32 @@
15
15
  from tn.chinese.rules.cardinal import Cardinal
16
16
  from tn.processor import Processor
17
17
 
18
- from pynini import string_file
18
+ from pynini import cross, string_file
19
19
  from pynini.lib.pynutil import delete, insert
20
20
 
21
21
 
22
22
  class Math(Processor):
23
23
 
24
24
  def __init__(self):
25
- super().__init__(name='math')
25
+ super().__init__(name="math")
26
26
  self.build_tagger()
27
27
  self.build_verbalizer()
28
28
 
29
29
  def build_tagger(self):
30
- operator = string_file('tn/chinese/data/math/operator.tsv')
30
+ operator = string_file("tn/chinese/data/math/operator.tsv")
31
+ # When it appears alone, it is treated as punctuation
32
+ symbols = (
33
+ cross("~", "到")
34
+ | cross(":", "比")
35
+ | cross("<", "小于")
36
+ | cross(">", "大于")
37
+ )
31
38
 
32
39
  number = Cardinal().number
33
- tagger = (number + ((delete(' ').ques + operator + delete(' ').ques +
34
- number).plus).ques)
40
+ tagger = (
41
+ number
42
+ + (delete(" ").ques + (operator | symbols) + delete(" ").ques + number).star
43
+ )
35
44
  tagger |= operator
36
45
  tagger = insert('value: "') + tagger + insert('"')
37
46
  self.tagger = self.add_tokens(tagger)
@@ -35,8 +35,6 @@ class Measure(Processor):
35
35
  to = cross('-', '到') | cross('~', '到') | accep('到')
36
36
 
37
37
  number = Cardinal().number
38
- percent = insert('百分之') + number + delete('%')
39
-
40
38
  number @= self.build_rule(cross('二', '两'), '[BOS]', '[EOS]')
41
39
  # 1-11个,1个-11个
42
40
  prefix = number + (rmspace + units).ques + to
@@ -55,8 +53,7 @@ class Measure(Processor):
55
53
  prefix = cardinal + (rmspace + unit).ques + to
56
54
  annual = prefix.ques + cardinal + unit
57
55
 
58
- tagger = insert('value: "') + (measure | percent
59
- | annual) + insert('"')
56
+ tagger = insert('value: "') + (measure | annual) + insert('"')
60
57
 
61
58
  # 10km/h
62
59
  rmsign = rmspace + delete('/') + rmspace
tn/en_tn_tagger.fst ADDED
Binary file
Binary file
tn/english/__init__.py ADDED
File without changes
File without changes
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
File without changes
File without changes
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
File without changes
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
File without changes
File without changes
File without changes
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
File without changes
@@ -0,0 +1,92 @@
1
+ # Copyright (c) 2022 Zhendong Peng (pzd17@tsinghua.org.cn)
2
+ # Copyright (c) 2024 Xingchen Song (sxc19@tsinghua.org.cn)
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from tn.processor import Processor
17
+ from tn.english.rules.cardinal import Cardinal
18
+ from tn.english.rules.ordinal import Ordinal
19
+ from tn.english.rules.decimal import Decimal
20
+ from tn.english.rules.fraction import Fraction
21
+ from tn.english.rules.word import Word
22
+ from tn.english.rules.date import Date
23
+ from tn.english.rules.time import Time
24
+ from tn.english.rules.measure import Measure
25
+ from tn.english.rules.money import Money
26
+ from tn.english.rules.telephone import Telephone
27
+ from tn.english.rules.electronic import Electronic
28
+ from tn.english.rules.whitelist import WhiteList
29
+ from tn.english.rules.punctuation import Punctuation
30
+
31
+ from pynini.lib.pynutil import add_weight, delete
32
+ from importlib_resources import files
33
+
34
+
35
+ class Normalizer(Processor):
36
+
37
+ def __init__(self, cache_dir=None, overwrite_cache=False):
38
+ super().__init__(name='en_normalizer', ordertype="en_tn")
39
+ if cache_dir is None:
40
+ cache_dir = files("tn")
41
+ self.build_fst('en_tn', cache_dir, overwrite_cache)
42
+
43
+ def build_tagger(self):
44
+ cardinal = add_weight(Cardinal().tagger, 1.0)
45
+ ordinal = add_weight(Ordinal().tagger, 1.0)
46
+ decimal = add_weight(Decimal().tagger, 1.0)
47
+ fraction = add_weight(Fraction().tagger, 1.0)
48
+ date = add_weight(Date().tagger, 0.99)
49
+ time = add_weight(Time().tagger, 1.00)
50
+ measure = add_weight(Measure().tagger, 1.00)
51
+ money = add_weight(Money().tagger, 1.00)
52
+ telephone = add_weight(Telephone().tagger, 1.00)
53
+ electronic = add_weight(Electronic().tagger, 1.00)
54
+ word = add_weight(Word().tagger, 100)
55
+ whitelist = add_weight(WhiteList().tagger, 1.00)
56
+ punct = add_weight(Punctuation().tagger, 2.00)
57
+ # TODO(xcsong): add roman
58
+ tagger = punct.star + \
59
+ (cardinal | ordinal | word
60
+ | date | decimal | fraction
61
+ | time | measure | money
62
+ | telephone | electronic
63
+ | whitelist
64
+ | punct).optimize() + (punct.plus | self.DELETE_SPACE)
65
+ # delete the last space
66
+ self.tagger = tagger.star @ self.build_rule(delete(' '), r='[EOS]')
67
+
68
+ def build_verbalizer(self):
69
+ cardinal = Cardinal().verbalizer
70
+ ordinal = Ordinal().verbalizer
71
+ decimal = Decimal().verbalizer
72
+ fraction = Fraction().verbalizer
73
+ word = Word().verbalizer
74
+ date = Date().verbalizer
75
+ time = Time().verbalizer
76
+ measure = Measure().verbalizer
77
+ money = Money().verbalizer
78
+ telephone = Telephone().verbalizer
79
+ electronic = Electronic().verbalizer
80
+ whitelist = WhiteList().verbalizer
81
+ punct = Punctuation().verbalizer
82
+ verbalizer = \
83
+ (cardinal | ordinal | word
84
+ | date | decimal
85
+ | fraction | time
86
+ | measure | money
87
+ | telephone
88
+ | electronic
89
+ | whitelist
90
+ | punct).optimize() + punct.ques + self.INSERT_SPACE
91
+ self.verbalizer = verbalizer.star @ self.build_rule(delete(' '),
92
+ r='[EOS]')
File without changes
@@ -0,0 +1,186 @@
1
+ # Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
2
+ # Copyright (c) 2024, WENET COMMUNITY. Xingchen Song (sxc19@tsinghua.org.cn).
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import pynini
17
+ from pynini.examples import plurals
18
+ from pynini.lib import pynutil
19
+
20
+ from tn.processor import Processor
21
+ from tn.utils import get_abs_path
22
+
23
+
24
+ class Cardinal(Processor):
25
+
26
+ def __init__(self, deterministic: bool = False):
27
+ """
28
+ Args:
29
+ deterministic: if True will provide a single transduction option,
30
+ for False multiple transduction are generated (used for audio-based normalization)
31
+ """
32
+ super().__init__('cardinal', ordertype="en_tn")
33
+ self.deterministic = deterministic
34
+ self.build_tagger()
35
+ self.build_verbalizer()
36
+
37
+ def build_tagger(self):
38
+ """
39
+ Finite state transducer for classifying cardinals, e.g.
40
+ -23 -> cardinal { negative: "true" integer: "twenty three" }
41
+ """
42
+ # TODO replace to have "oh" as a default for "0"
43
+ graph = pynini.Far(
44
+ get_abs_path(
45
+ "english/data/number/cardinal_number_name.far")).get_fst()
46
+ graph_au = pynini.Far(
47
+ get_abs_path(
48
+ "english/data/number/cardinal_number_name_au.far")).get_fst()
49
+ self.graph_hundred_component_at_least_one_none_zero_digit = (
50
+ pynini.closure(self.DIGIT, 2, 3)
51
+ | pynini.difference(self.DIGIT, pynini.accep("0"))) @ graph
52
+
53
+ graph_digit = pynini.string_file(
54
+ get_abs_path("english/data/number/digit.tsv"))
55
+ graph_zero = pynini.string_file(
56
+ get_abs_path("english/data/number/zero.tsv"))
57
+
58
+ single_digits_graph = pynini.invert(graph_digit | graph_zero)
59
+ self.single_digits_graph = single_digits_graph + pynini.closure(
60
+ self.INSERT_SPACE + single_digits_graph)
61
+
62
+ if not self.deterministic:
63
+ # for a single token allow only the same normalization
64
+ # "007" -> {"oh oh seven", "zero zero seven"} not {"oh zero seven"}
65
+ single_digits_graph_zero = pynini.invert(graph_digit | graph_zero)
66
+ single_digits_graph_oh = pynini.invert(graph_digit) | pynini.cross(
67
+ "0", "oh")
68
+
69
+ self.single_digits_graph = single_digits_graph_zero + pynini.closure(
70
+ self.INSERT_SPACE + single_digits_graph_zero)
71
+ self.single_digits_graph |= single_digits_graph_oh + pynini.closure(
72
+ self.INSERT_SPACE + single_digits_graph_oh)
73
+
74
+ single_digits_graph_with_commas = pynini.closure(
75
+ self.single_digits_graph + self.INSERT_SPACE, 1,
76
+ 3) + pynini.closure(
77
+ pynutil.delete(",") + single_digits_graph +
78
+ self.INSERT_SPACE + single_digits_graph +
79
+ self.INSERT_SPACE + single_digits_graph, 1)
80
+
81
+ graph = (pynini.closure(self.DIGIT, 1, 3) +
82
+ (pynini.closure(pynutil.delete(",") + self.DIGIT**3)
83
+ | pynini.closure(self.DIGIT**3))) @ graph
84
+
85
+ self.graph = graph
86
+ self.graph_with_and = self.add_optional_and(graph)
87
+
88
+ if self.deterministic:
89
+ long_numbers = pynini.compose(self.DIGIT**(5, ...),
90
+ self.single_digits_graph).optimize()
91
+ self.long_numbers = plurals._priority_union(
92
+ long_numbers, self.graph_with_and,
93
+ pynini.closure(self.VCHAR)).optimize()
94
+ cardinal_with_leading_zeros = pynini.compose(
95
+ pynini.accep("0") + pynini.closure(self.DIGIT),
96
+ self.single_digits_graph)
97
+ final_graph = self.long_numbers | cardinal_with_leading_zeros
98
+ final_graph |= self.add_optional_and(graph_au)
99
+ else:
100
+ leading_zeros = pynini.compose(
101
+ pynini.closure(pynini.accep("0"), 1), self.single_digits_graph)
102
+ cardinal_with_leading_zeros = (
103
+ leading_zeros + self.INSERT_SPACE + pynini.compose(
104
+ pynini.closure(self.DIGIT), self.graph_with_and))
105
+ self.long_numbers = self.graph_with_and | pynutil.add_weight(
106
+ self.single_digits_graph, 0.0001)
107
+ # add small weight to non-default graphs to make sure the deterministic option is listed first
108
+ final_graph = (self.long_numbers
109
+ | pynutil.add_weight(
110
+ single_digits_graph_with_commas, 0.0001)
111
+ | cardinal_with_leading_zeros).optimize()
112
+
113
+ one_to_a_replacement_graph = (
114
+ pynini.cross("one hundred", "a hundred")
115
+ | pynini.cross("one thousand", "thousand")
116
+ | pynini.cross("one million", "a million"))
117
+ final_graph |= pynini.compose(
118
+ final_graph,
119
+ one_to_a_replacement_graph.optimize() +
120
+ pynini.closure(self.VCHAR)).optimize()
121
+ # remove commas for 4 digits numbers
122
+ four_digit_comma_graph = (
123
+ self.DIGIT - "0") + pynutil.delete(",") + self.DIGIT**3
124
+ final_graph |= pynini.compose(four_digit_comma_graph.optimize(),
125
+ final_graph).optimize()
126
+
127
+ self.final_graph = final_graph
128
+ optional_minus_graph = pynini.closure(
129
+ pynutil.insert("negative: ") + pynini.cross("-", "\"true\" "), 0,
130
+ 1)
131
+ final_graph = optional_minus_graph + pynutil.insert(
132
+ "integer: \"") + final_graph + pynutil.insert("\"")
133
+ final_graph = self.add_tokens(final_graph)
134
+ self.tagger = final_graph.optimize()
135
+
136
+ def add_optional_and(self, graph):
137
+ graph_with_and = graph
138
+
139
+ graph_with_and = pynutil.add_weight(graph, 0.00001)
140
+ not_quote = pynini.closure(self.NOT_QUOTE)
141
+ no_thousand_million = pynini.difference(
142
+ not_quote, not_quote + pynini.union("thousand", "million") +
143
+ not_quote).optimize()
144
+ integer = (not_quote + pynutil.add_weight(
145
+ pynini.cross("hundred ", "hundred and ") + no_thousand_million,
146
+ -0.0001)).optimize()
147
+
148
+ no_hundred = pynini.difference(
149
+ pynini.closure(self.VCHAR),
150
+ not_quote + pynini.accep("hundred") + not_quote).optimize()
151
+ integer |= (not_quote + pynutil.add_weight(
152
+ pynini.cross("thousand ", "thousand and ") + no_hundred,
153
+ -0.0001)).optimize()
154
+
155
+ optional_hundred = pynini.compose((self.DIGIT - "0")**3,
156
+ graph).optimize()
157
+ optional_hundred = pynini.compose(
158
+ optional_hundred,
159
+ pynini.closure(self.VCHAR) + pynini.cross(" hundred", "") +
160
+ pynini.closure(self.VCHAR))
161
+ graph_with_and |= pynini.compose(graph, integer).optimize()
162
+ graph_with_and |= optional_hundred
163
+ return graph_with_and
164
+
165
+ def build_verbalizer(self):
166
+ """
167
+ Finite state transducer for verbalizing cardinal, e.g.
168
+ cardinal { negative: "true" integer: "23" } -> minus twenty three
169
+ """
170
+ optional_sign = pynini.cross("negative: \"true\"", "minus ")
171
+ if not self.deterministic:
172
+ optional_sign |= pynini.cross("negative: \"true\"", "negative ")
173
+ optional_sign |= pynini.cross("negative: \"true\"", "dash ")
174
+
175
+ self.optional_sign = pynini.closure(optional_sign + self.DELETE_SPACE,
176
+ 0, 1)
177
+
178
+ integer = pynini.closure(self.NOT_QUOTE)
179
+
180
+ self.integer = self.DELETE_SPACE + pynutil.delete(
181
+ "\"") + integer + pynutil.delete("\"")
182
+ integer = pynutil.delete("integer:") + self.integer
183
+
184
+ self.numbers = self.optional_sign + integer
185
+ delete_tokens = self.delete_tokens(self.numbers)
186
+ self.verbalizer = delete_tokens.optimize()