5

短縮版:

正規表現内のすべての名前付きグループをdatadictからの対応するデータに置き換える関数を作成したいと思います。例えば:

Input: expr=r"/(?P<something>\w+)/whatever/(?P<something2>\w+)" data={"something":123, "something2": "thing"}
Output: "/123/whatever/thing"

しかし、私はそれを行う方法がわかりません。

いくつかの追加情報:

名前とパターンを含み、re.searchを使用しようとしているタプルのトラフリストを反復するコードがあります。re.searchが指定された文字列と一致する場合、現在のタプルとgroupdict()(re.searchからのデータを含むdict)から名前を返します。

これがコードです

class UrlResolver():
def __init__(self):
    self.urls = {}

def parse(self, app, url):
    for pattern in self.urls[app]:
        data = re.search(pattern[1], url)
        if data:
            return {"name": pattern[0], "data": data.groupdict()}

今、私は関数を作成したいと思います:

def compose(self, app, name, data):
    for pattern in self.url[app]:
        if pattern[0] == name:
            return string composed from regex expression and data from data dict.

上記の関数は、すべての名前付きグループをdatadictからの対応するデータに置き換える必要があります。

解決

Hans Then(Thanks!)から提供された回答と、ここにある他の情報を使用すると、解決策が得られます。

    def _group_replacer(data, match):
        data_key = match.group(1)
        return data[data_key]

    expression = r"\([^\(]*<([^<]*)>[^\(]*\)"
    expression = re.compile(expression)

    reversed = re.sub(expression, partial(_group_replacer, data), string)

関数「部分」はfunctoolsからインポートできます

4

2 に答える 2

5

機能をご覧くださいre.sub()。この関数は、2 番目のパラメーターとして置換関数を使用して呼び出すことができます。http://docs.python.org/2/library/re.htmlを参照してください

その関数は、自分で定義する必要があります。パラメーターとして一致オブジェクトを取得する必要があります。その中で、一致オブジェクトを見て、一致グループを抽出し、それらを辞書の値に置き換える必要があります。

グループをループしてそれらを呼び出すことにより、元の文字列から置き換える必要のない文字列からテキストを抽出できstart, end = span(group)ます。

編集

元の質問を読み違えました。正規表現からの一致を置換するのではなく、正規表現自体を置換したいことがわかりました。この場合、困難な部分は、指定された正規表現に一致する正規表現を作成することです。私の解決策はまだ有効ですが、もう少し簡単になる可能性があります。

適切な苦行を行うために、次の例を作成しました。

d = { 'something': 'completely',
      'something2': 'different' }

def repl(m):
    s = m.group(1)
    return d[s]

s = "/(?P<something>\w+)/whatever/(?P<something2>\w+)"
p = re.compile(r'\(\?P<(.*?)>\\w\+\)')

print p.sub(repl, s)

これは印刷されます

/completely/whatever/different

于 2012-11-07T11:33:13.460 に答える
1

FJ here が示す方法を使用すると、次のように置換を実行できます。

import re

data = {"something" : 123, "something2" : "thing"}
expr = r"/(?P<something>\w+)/whatever/(?P<something2>\w+)"

def matchsub(match, data):
    result = list(match.string)
    pat = match.re
    # print(pat)
    for key, index in pat.groupindex.items():
        # print(key, index, data[key], match.start(index), match.end(index))
        result[match.start(index):match.end(index)] = str(data[key])
    return ''.join(result)

result = matchsub(re.search(expr, "hi/ABC/whatever/DEF/there"), data)
print(result)

収量

hi/123/whatever/thing/there
于 2012-11-07T13:32:19.197 に答える