File size: 2,307 Bytes
29f25be | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | """Two-dictionary orthographic kana checks for evaluation preparation only."""
import re
from importlib.metadata import version
KANA = re.compile(r"[ァ-ヺー。、!?「」『』()・:,,.!?]+")
def katakana(text):
return "".join(chr(ord(c) + 0x60) if "ぁ" <= c <= "ゖ" else c for c in text)
class DualReading:
def __init__(self):
import fugashi
from sudachipy import Dictionary, SplitMode
self.mecab = fugashi.Tagger()
self.sudachi = Dictionary().create()
self.mode = SplitMode.C
self.versions = {
n: version(n) for n in ("fugashi", "unidic-lite", "sudachipy", "sudachidict-core")
}
def analyse(self, text, start=0):
"""Read a suffix in its sentence, rejecting boundaries inside words."""
left, right, unknown = [], [], []
offset = 0
for word in self.mecab(text):
surface = word.surface
end = offset + len(surface)
if offset < start < end:
unknown.append("boundary_inside_unidic_word")
if offset < start:
offset = end
continue
offset = end
if word.is_unk:
unknown.append(surface)
if KANA.fullmatch(katakana(surface)):
left.append(katakana(surface))
elif word.feature.kana:
left.append(word.feature.kana)
else:
left.append(surface)
unknown.append(surface)
for word in self.sudachi.tokenize(text, self.mode):
surface = word.surface()
if word.begin() < start < word.end():
unknown.append("boundary_inside_sudachi_word")
if word.begin() < start:
continue
if KANA.fullmatch(katakana(surface)):
right.append(katakana(surface))
else:
right.append(word.reading_form())
if word.is_oov():
unknown.append(surface)
a, b = "".join(left), "".join(right)
return {
"unidic": a,
"sudachi": b,
"agreement": a == b,
"unknown": sorted(set(unknown)),
"kana_only": bool(KANA.fullmatch(a) and KANA.fullmatch(b)),
}
|