2017-06-07 32 views
1

期望的任務是將v替換爲u變音符對應項。str.maketrans或re.sub用於Python3中的unicode

我能做到這樣:

>>> replacements = {'v':'u', u'v̄':u'ǖ', u'v́':u'ǘ', u'v̌':u'ǚ', u'v̀':u'ǜ'} 
>>> s = u'lv́' 
>>> for v, u in replacements.items(): 
...  s = s.replace(v, u) 
... 
>>> s 
'lǘ' 

但是,當我與str.maketrans試了一下,它拋出一個ValueError:

>>> str.maketrans({'v':'u', u'v̄':u'ǖ', u'v́':u'ǘ', u'v̌':u'ǚ', u'v̀':u'ǜ'}) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: string keys in translate table must be of length 1 

是否有可能使用unicode的str.maketransstr.tranlsate

如果不是,那麼適當的單個正則表達式替換是否會實現所需的輸出?或者它也不可能?

+0

我不認爲'maketrans'會在這裏工作。我認爲一個正則表達式也不會真正起作用。 (你可以讓一個調用每個替換函數的函數,但這似乎是一個奇怪的解決方案。)你的原代碼有什麼問題? – smarx

+0

無論任何形式的「v」是否出現在原始字符串中,原始代碼都會進行5次操作。我認爲'str.maketrans'和'str.translate'是可能的,因爲它對於非Unicode字符串通常是正常工作的。 – alvas

+0

我相信'str.maketrans'可以在unicode下正常工作,但只有映射的「from」一邊由長度爲1的字符串組成時纔有效。 – smarx

回答

1

我希望這會有所幫助,但我不確定它比您的原始代碼更有效。 (我假設你後性能提升是?)

import re 

replacements = {'v': 'u', 'v̀': 'ǜ', 'v̌': 'ǚ', 'v́': 'ǘ', 'v̄': 'ǖ'} 
def replace(match): 
    return replacements[match.group(0)] 

# alternative 1 
assert re.sub(r'v̄|v́|v̌|v̀|v', replace, 'lv́vv̌') == 'lǘuǚ' 

# alternative 2 
assert re.sub(r'v[́̄̌̀]?', replace, 'lv́vv̌') == 'lǘuǚ' 

注意的是,在第一替代方案,它把v最後在正則表達式是非常重要的。否則,它會首先匹配(而不是更長的序列)。

+0

很酷!我沒有意識到're.sub' =的這種用法) – alvas