2016-11-24 16 views
1

私はPythonの正規表現ライブラリでgroupメソッドを理解するのに苦労しています。ここでは、一致するオブジェクトに応じて文字列の置換を試みます。私は(それぞれrep1rep2付き)my_dict辞書内の特定の文字列と一致するオブジェクト(この例では+\n)を交換したい、ある一致するオブジェクト(Python)に基づく文字列の置換

content = ''' 
Blah - blah \n blah * blah + blah. 
''' 

regex = r'[+\-*/]' 

for mobj in re.finditer(regex, content): 
    t = mobj.lastgroup 
    v = mobj.group(t) 

    new_content = re.sub(regex, repl_func(mobj), content) 

def repl_func(mobj): 
    my_dict = { '+': 'rep1', '\n': 'rep2'} 
    try: 
     match = mobj.group(0) 
    except AttributeError: 
     match = '' 
    else: 
     return my_dict.get(match, '') 

print(new_content) 

をしかし、私はvを計算するときにIndexError続いtためNoneを取得:questionanswerこのことからわかるように

、 私はこれを試してみました。

すべての説明とサンプルコードは理解できます。

+0

それはあなたのコードが行うことになっているものを推測するのは難しい(多くの構文エラーがあります、インデントが壊れている、ロジックは不明)。あなたが達成したいことを記述する例を提供する方が良いでしょう。 – TomR8

+0

@ TomR8お詫び!私はすべての構文の問題と誤字を修正しました(うまくいけば)。 –

答えて

2

正規表現と改行が一致しないため、'\n': 'rep2'は使用されません。それ以外の場合は、\nを正規表現に追加してください:r'[\n+*/-]'あなたの正規表現は、任意のnamed capturing groupsが含まれていないため

次に、あなたがNoneを取得し、re docs参照:

match.lastgroup
最後にマッチした取り込みグループの名前、またはNoneグループがなかった場合名前がある場合、またはグループが全く一致しない場合はです。

マッチを使用して置き換えるには、あなたも代替としてラムダとre.subを使用し、re.finditerを使用する必要はありません。

import re 
content = ''' 
Blah - blah \n blah * blah + blah. 
''' 

regex = r'[\n+*/-]' 
my_dict = { '+': 'rep1', '\n': 'rep2'} 
new_content = re.sub(regex, lambda m: my_dict.get(m.group(),""), content) 
print(new_content) 
# => rep2Blah blah rep2 blah blah rep1 blah.rep2 

Python demo

m.group()全体を取得を参照してください。一致(全体の一致はmatch.group(0)に格納されます)。あなたがパターンにエスケープ括弧のペアを持っていた場合、それはcapturing groupを作成し、あなたがWiktor第者の真の神託の答えのにもかかわらず、などm.group(1)との最初の1、

2

にアクセスすることができ、質問がまだありますなぜOPのorginalアルゴリズムwouldn仕事はありません。

new_content = re.sub(regex, repl_func(mobj), content)の呼び出しはすべてが非常に最初の試合の置換値でregexのと一致する代用します: は、基本的には2つの問題があります。

正しい呼び出しはnew_content = re.sub(regex, repl_func, content)である必要があります。 hereと記載されているように、repl_funcは現在の一致オブジェクトで動的に呼び出されます。 - 彼はただ関数定義自体を処分したラムダ式を使用して

my_dict = {'\n': '', '+':'rep1', '*':'rep2', '/':'rep3', '-':'rep4'} 
def repl_func(mobj): 
    global my_dict 
    return my_dict.get(mobj.group(0), '') 

これはWiktor第のソリューションと同等です:

repl_func(mobj)を簡略化することができるいくつかの不要な例外処理を、行います。

この修正では、同じ計算を複数回実行するので、for mobj in re.finditer(regex, content):ループはスーパーフルーとなりました。

完全性のために、re.finditer()を使用した解決策があります。それはマッチしたスライスcontentから結果文字列を構築します。

my_regx = r'[\n+*/-]' 
my_dict = {'\n': '', '+':'rep1'  , '*':'rep2', '/':'rep3', '-':'rep4'} 
content = "A*B+C-D/E" 
res = "" 
cbeg = 0 
for mobj in re.finditer(my_regx, content): 
    # get matched string and its slice indexes 
    mstr = mobj.group(0) 
    mbeg = mobj.start() 
    mend = mobj.end() 

    # replace matched string 
    mrep = my_dict.get(mstr, '') 

    # append non-matched part of content plus replacement 
    res += content[cbeg:mbeg] + mrep 

    # set new start index of remaining slice 
    cbeg = mend 

# finally add remaining non-matched slice 
res += content[cbeg:] 
print (res) 
関連する問題