In English, "Sh" is two letters. In other languages it's considered a single letter. I'm trying to calculate the length of a string in a Unicode aware way, with this in mind. I'm imagining a function like
def count_letters(my_string, lang="en")
But here's how I would do that for just one language, using a library that has had no new versions since 2015, uniseg
:
from uniseg.graphemecluster import grapheme_clusters
def albanian_digraphs(s, breakables):
digraphs = ["Dh", "Gj", "Ll", "Nj", "Rr", "Sh", "Th", "Xh", "Zh"]
digraphs += [d.lower() for d in digraphs]
for i, breakable in enumerate(breakables):
for first, second in digraphs:
if s.endswith(first, 0, i) and s.startswith(second, i):
yield 0
break
else:
yield breakable
# from https://sq.wiktionary.org/wiki/Speciale:PrefixIndex?prefix=dh
for text in ('dhallanik', 'dhelpëror', 'dhembshurisht', 'dhevështrues', 'dhimbshëm', 'dhjamosje', 'dhjetëballësh', 'dhjetëminutësh', 'dhogaç', 'dhogiç', 'dhomë-muze', 'dhuratë', 'dhëmbinxhi', 'dhëmbçoj', 'dhëmbëkatarosh'):
print(list(grapheme_clusters(text, albanian_digraphs)))
#['dh', 'a', 'll', 'a', 'n', 'i', 'k']
#['dh', 'e', 'l', 'p', 'ë', 'r', 'o', 'r']
#['dh', 'e', 'm', 'b', 'sh', 'u', 'r', 'i', 'sh', 't']
#['dh', 'e', 'v', 'ë', 'sh', 't', 'r', 'u', 'e', 's']
#['dh', 'i', 'm', 'b', 'sh', 'ë', 'm']
#['dh', 'j', 'a', 'm', 'o', 's', 'j', 'e']
#['dh', 'j', 'e', 't', 'ë', 'b', 'a', 'll', 'ë', 'sh']
#['dh', 'j', 'e', 't', 'ë', 'm', 'i', 'n', 'u', 't', 'ë', 'sh']
#['dh', 'o', 'g', 'a', 'ç']
#['dh', 'o', 'g', 'i', 'ç']
#['dh', 'o', 'm', 'ë', '-', 'm', 'u', 'z', 'e']
#['dh', 'u', 'r', 'a', 't', 'ë']
#['dh', 'ë', 'm', 'b', 'i', 'n', 'xh', 'i']
#['dh', 'ë', 'm', 'b', 'ç', 'o', 'j']
#['dh', 'ë', 'm', 'b', 'ë', 'k', 'a', 't', 'a', 'r', 'o', 'sh']
s
is the original string andbreakables
is a list of similar length containing zeroes or ones. Ones mean break before the corresponding letter, zeroes mean keep the corresponding letter in the same grapheme than the previous one. The function's purpose is to modifybreakables
before breaks are applied tos
. \$\endgroup\$