0

私はファイルタイプを変換するパッケージをハッキングしており、ユーザーが変換(Python関数)とファイル名の変更方法の正規表現を指定できるようにしています。

あるケースでは、一連の正規表現と単一の出力文字列があり、すべての正規表現グループの結合で拡張したいと考えています。

import re
re_strings = ['(.*).txt', '(.*).ogg', 'another(?P<name>.*)']
regexes = map(re.compile, re_strings]
input_files = ['cats.txt', 'music.ogg', 'anotherpilgrim.xls']
matches = [regexes[i].match(input_files[i]) for i in range(len(regexes))]

outputstr = 'Text file about: \1, audio file about: \2, and another file on \g<name>.'
# should be 'Text file about: cats, audio file about: music, and another file on pilgrim.xls'

正規表現を結合して拡張したいと思いoutputstrます(おそらく、参照には連結の方が理にかなってい\2ますか?)。reを連結して、未使用の文字で区切ることができます。

final_re = re.compile('\n'.join(re_strings))
final_files = '\n'.join(input_files)
match = final_re.search(final_files)

ただし、これにより、ファイル名の一部だけでなく、ファイル全体と一致するようになります。私はファイルの間にキャッチオールグループを入れることができます(.*?)が、それは確かにグループ参照を台無しにし、元のパターンを台無しにする可能性があります(私は制御できません)。名前付きグループをどこにでも強制して、すべての正規表現.groupdict()を結合することもできると思います。

Pythonは部分的な拡張を許可しないため、すべてのグループ参照が有効である必要があるため、次のようにgroupdictに対して一連の拡張を行う可能性はありません。

for m in matches:
    outputstr = m.expand(outputstr)

アドバイスありがとうございます!

4

1 に答える 1

0

念のため、いくつかの正規表現の結果を結合し、それらすべてを置換する方法を次に示します。

いくつかのクエリ文字列と、いくつかの正規表現の一致が与えられた場合:

import re

query_str = ["abcdyyy", "hijkzzz"]
re_pattern = [r"(a)(b)(?P<first_name>c)(d)",
              r"(h)(i)(?P<second_name>j)(k)"]

# match each separately
matches= [re.search(p,q) for p,q in 
          zip(re_pattern, query_str)]

すべての検索結果を組み合わせて置換文字列を作成したいと思います。

replacement = r"[\4_\g<first_name>_\2_\1:\5:\6:\8:\g<second_name>]"

これを行うには、次のことが必要です。

  1. 検索結果をマージする
  2. マージされた結果の代わりにプロキシを用意する (match_substitute)
  3. "first_name" (pattern_substitute) などの名前付きグループを処理するプロキシ オブジェクトを用意する

これは、次のコードによって処理されます。結果は「結果」にあります:

import sre_parse

#
#   dummy object to provide group() function and "string" member variable
#
class match_substitute:
    def __init__(self, matches): 
        self.data = []
        for m in matches:
            self.data.extend(m.groups())
        self.string = ""
    # regular expression groups count from 1 not from zero!
    def group(self, ii):
        return self.data[ii - 1]



#
#   dummy object to provide groupindex dictionary for named groups
#
class pattern_substitute:
    def __init__(self, matches, re_pattern): 
        #
        #   Named group support
        #   Increment indices so they are point to the correct position
        #       in the merged list of matching groups
        #
        self.groupindex = dict()
        offset = 0
        for p, m in zip(re_pattern, matches):
            for k,v in sre_parse.parse(p).pattern.groupdict.iteritems():
                self.groupindex[k] = v + offset
            offset += len(m.groups())



match   = match_substitute(matches)
pattern = pattern_substitute(matches, re_pattern)

#
#   parse and substitute
#
template = sre_parse.parse_template(replacement, pattern)
result = sre_parse.expand_template(template, match)
于 2013-01-09T11:46:09.687 に答える