some nice waysは、複数の文字列を同時にPythonで置換する処理を行います。しかし、私はそれを行うことができ、後方参照をサポートする効率的な機能を作成するのに問題があります。Pythonはバックリファレンスをサポートしている間に複数の文字列を置き換えます
表現/置換用語の辞書を使用してください。置換用語には、式と一致するものに逆参照が含まれている場合があります。
しかし
def replaceAll(repdict, text):
repdict = dict((re.escape(k), v) for k, v in repdict.items())
pattern = re.compile("|".join(repdict.keys()))
return pattern.sub(lambda m: repdict[re.escape(m.group(0))], text)
:
repdict = {'&&':'and', '||':'or', '!([a-zA-Z_])':'not \1'}
(\注1)私はSO後方参照が含まれていない表現/交換のペアのため正常に動作され、以下の機能に最初に述べた答えを置きます逆参照を含むキーでは機能しません。
>>> replaceAll(repldict, "!newData.exists() || newData.val().length == 1")
'!newData.exists() or newData.val().length == 1'
私は手動で行うとうまくいきます。例えば:予想通り
pattern = re.compile("!([a-zA-Z_])")
pattern.sub(r'not \1', '!newData.exists()')
作品:派手な機能で
'not newData.exists()'
を、エスケープは後方参照を使用して、キーをめちゃくちゃしているように見えるので、それは何も一致することはありません。
私は結局これを思いついた。しかし、入力パラメータにbackrefsを支援する問題が解決されていないことに注意してください、私はちょうど代用機能で手動で処理するよ:
def replaceAll(repPat, text):
def replacer(obj):
match = obj.group(0)
# manually deal with exclamation mark match..
if match[:1] == "!": return 'not ' + match[1:]
# here we naively escape the matched pattern into
# the format of our dictionary key
else: return repPat[naive_escaper(match)]
pattern = re.compile("|".join(repPat.keys()))
return pattern.sub(replacer, text)
def naive_escaper(string):
if '=' in string: return string.replace('=', '\=')
elif '|' in string: return string.replace('|', '\|')
else: return string
# manually escaping \ and = works fine
repPat = {'!([a-zA-Z_])':'', '&&':'and', '\|\|':'or', '\=\=\=':'=='}
replaceAll(repPat, "(!this && !that) || !this && foo === bar")
戻り値:
は'(not this and not that) or not this'
だから、誰もが持っている場合逆参照をサポートするマルチストリング置換関数を作成し、その置換された用語を入力として受け入れる方法を考えれば、私はあなたのフィードバックを非常に高く評価します。
'replDict'のキーに必要な正規表現エスケープを含めないでください。なぜ' re.escape'を適用する必要はありませんか? – jonrsharpe
それはエスケープする問題以上のものです: '!([a-zA-Z])'はあなたの置き換えられたdictのキーではない '!n'とマッチします。 dictを使用して固定文字列を置き換えることはできます。 –
@jonrsharpeありがとうございます、それは私が最後の例でやらなければならなかったことです。しかし、それは非常にclunkyです、例えば、一度マッチが行われたら、私はエスケープマッチ(naive_escaperを使用)に一致を変換するだけで、私は辞書(repPat)の置換値を参照することができます。私はおそらくreplacer関数に渡されている 'obj'パラメータがすでにどこかに入っていると考えているので、数時間の睡眠の後でこれをさらに調べます:-) – fzzylogic