我目前正在用 Python 撰寫一個程式,該程式應該將一種語言中的所有字符從一種正字法音譯成另一種。這里有兩件事,一是已經解決了,二是有問題。第一步,將源拼寫中的字符轉換為目標拼寫,例如
? -> sh
? -> lh
m? -> m’
l? -> l’
(ffr:看起來像撇號的字符是一個單引號。)
更接近問題:在某些情況下,有一些以標準方式撰寫的字素(m', n', l', y', w')根據它們周圍的內容以不同的方式撰寫。具體來說,如果字素緊跟在元音之后和在元音之前并且在字素之前的元音在層次結構中處于更高的“級別” ,則'字符可以移動到輔音字符之前。這是一個復雜的規則來解釋,但這里有一些例子,我包括音譯的第一階段:
?m?? -> um’u -> um’u (no change)
?m?i -> um’i -> um’i (no change)
im?? -> im’u -> i’mu (’ character moves to precede; i > u)
em?i -> e’mi -> em’i (’ character moves to precede; e > i)
層次結構是'字符應該向最高層次結構的元音移動:e > i > a > u
這是我處理第二步的代碼,幾乎可以完成。它非常干凈,簡潔地解決了這個問題:
import re
def glottalized_resonant_mover(linestring):
'''
moves glottal character over according to glottalized resonant
hierarchy:
case description: VR’W for some vowels V, W; some glottalized
resonant R’
hierarchy: e > i > a > u
3 > 2 > 1 > 0
if h(V) > h(W), then string is V’RW
'''
hi_scores = {'e' : 3,
'i' : 2,
'a' : 1,
'u' : 0}
def hierarchy_sub(matchobj):
'''moves glottalized resonant if a vowel pulls it one way
or the other
'''
if hi_scores[matchobj.group(1)] > hi_scores[matchobj.group(4)]:
swap_string = ''.join(
[
matchobj.group(1),
matchobj.group(3),
matchobj.group(2),
matchobj.group(4)
]
)
return swap_string
else:
return matchobj.group(0)
glot_res_re = re.compile('(a|e|i|u)(l|m|n|w|y)(’)(a|e|i|u)')
swapstring = glot_res_re.sub(hierarchy_sub, linestring)
return swapstring
sample = ['’im’ush', 'ttham’uqwus', 'xwtsekwul’im’us']
for i in sample:
print(glottalized_resonant_mover(i))
因此,當此代碼被賦予音譯詞im'ush、ttham'uqwus和xwtsekwul'im'us時,它對前兩個詞非常有效,但對第三個詞則不然。總結清楚:
’im’ush' -> ’i’mush √
ttham’uqwus -> ttha’muqwus √
xwtsekwul’im’us -> xwtsekwul’im’us X should be: xwtsekwul’i’mus
問題是第三個單詞中有兩個捕獲組:有ul'i,然后有im'u,它們都共享i。
現在,這個程式被輸入文本行,第一階段的音譯發生,然后第二步應該發生。有些檔案長達數千行,而且這些檔案數量很多。我還打算實施其他一些事情(檢查單詞串列等),這將占用大量計算能力,所以我想盡可能快地保持這一點,同時仍然易于理解。
此外,我確實可以為每個序列撰寫一個序列,然后再替換一大堆字符序列,但這樣我就失去了一些可移植性以及以后輕松進行編輯的能力。
所以,如果應該有一個問題:解決這個問題的最佳方法是什么,它仍然保留了我原始解決方案的方法和一些品質?
uj5u.com熱心網友回復:
是的,只需要非常小的更改。
VR'W -> V'RW
其實只需要操作前3個字符,以'W'為必要條件,所以我們要解決的問題就變成了:
VR'(W) -> V'R
使用前瞻斷言: (? =...) 可以匹配 VR'(W)
以前的:VR'W
(a|e|i|u)(l|m|n|w|y)(')(a|e|i|u)
隨后的僅匹配三個字母,但期待一個W:VR'(W)
(a|e|i|u)(l|m|n|w|y)(')(?=(a|e|i|u))
所以'W'是條件,不在操作范圍內,可以再次匹配。
import re
def glottalized_resonant_mover(linestring):
'''
moves glottal character over according to glottalized resonant
hierarchy:
case description: VR’W for some vowels V, W; some glottalized
resonant R’
hierarchy: e > i > a > u
3 > 2 > 1 > 0
if h(V) > h(W), then string is V’RW
'''
hi_scores = {'e' : 3,
'i' : 2,
'a' : 1,
'u' : 0}
def hierarchy_sub(matchobj):
'''moves glottalized resonant if a vowel pulls it one way
or the other
'''
if hi_scores[matchobj.group(1)] > hi_scores[matchobj.group(4)]:
swap_string = ''.join(
[
matchobj.group(1),
matchobj.group(3),
matchobj.group(2),
#matchobj.group(4) <- Don't need the last one because 'lookahead'
]
)
return swap_string
else:
return matchobj.group(0)
glot_res_re = re.compile('(a|e|i|u)(l|m|n|w|y)(’)(?=(a|e|i|u))')
# glot_res_re = re.compile('(a|e|i|u)(l|m|n|w|y)(’)(a|e|i|u)')
swapstring = glot_res_re.sub( hierarchy_sub, linestring)
return swapstring
sample = ['’im’ush', 'ttham’uqwus', 'xwtsekwul’im’us']
answer =['’i’mush', 'ttha’muqwus', 'xwtsekwul’i’mus']
it1 = iter(sample)
it2 = iter(answer)
for i in sample:
print(next(it1),'->',glottalized_resonant_mover(i), "==", next(it2))
輸出:
’im’ush -> ’i’mush == ’i’mush
ttham’uqwus -> ttha’muqwus == ttha’muqwus
xwtsekwul’im’us -> xwtsekwul’i’mus == xwtsekwul’i’mus
uj5u.com熱心網友回復:
我不太清楚你在這里追求什么。特別是,您的代碼顯然并不總是按照您希望的方式執行(“它對前兩個單詞非常有效,但對第三個單詞不適用”),但是您沒有要求解決這個問題,也沒有給我們足夠的資訊來知道為什么第三個詞“錯了”。
所以我只是彌補;-)由于re.sub()不知道重疊,我會以“優先”順序匹配多次,只尋找形式的東西
(e)([lmnwy])(’)([iau])
第一的。一系列 3 個相似模式似乎捕獲了您給我們的所有規則,并且它們僅在某些東西實際上需要交換時才匹配。筆記:
您不必“手動”撰寫這些內容。下面的代碼構造它們。
不要強調速度。現在還為時過早,“數千行”實際上在現代盒子上處理應該是微不足道的。無論如何,這比您猜測的要快,因為除非需要進行替換,否則永遠不會產生呼叫替換函式的費用。
編輯:由于以這種方式替換是無條件的,因此我將其更改為使用固定的替換字串模板,而不是使用匹配物件引數呼叫替換函式。
R = "lmnwy"
V_in_order = "eiau"
pats = []
for i, vowel in enumerate(V_in_order[:-1]):
pat = f"({vowel})([{R}])(’)([{V_in_order[i 1:]}])"
print("pattern", repr(pat))
pats.append(re.compile(pat))
# Not needed!
# def sub(m):
# return m.group(1) m.group(3) m.group(2) m.group(4)
def glottalized_resonant_mover(s):
for p in pats:
s = p.sub(r'\1\3\2\4', s)
return s
sample = ['’im’ush', 'ttham’uqwus', 'xwtsekwul’im’us']
for i in sample:
print(i, "->", glottalized_resonant_mover(i))
在所有情況下,輸出似乎都符合您的要求:
pattern '(e)([lmnwy])(’)([iau])'
pattern '(i)([lmnwy])(’)([au])'
pattern '(a)([lmnwy])(’)([u])'
’im’ush -> ’i’mush
ttham’uqwus -> ttha’muqwus
xwtsekwul’im’us -> xwtsekwul’i’mus```
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/435998.html
上一篇:計算無窮大時,C#速度減慢30倍
