2

次の形式の ASCII ファイルに行があるとします。

{text1} {stringA} {text2} {stringB} {text3}

ここで{stringA}{stringB}は対象の部分文字列です。それらをそれぞれ「A」と「B」と呼びましょう。文字列{text1}{text2}、および{text3}は、A も B も含まない、任意の長さの (空の可能性がある) 文字列です。

私が Python でやりたいことは、単純に A と B を交換して、行が次のようになるようにすることです。

{text1} {stringA} {text2} {stringB} {text3}

{text1} {stringB} {text2} {stringA} {text3}

ここで何か助けていただければ幸いです。この質問について助けを得ることで、Python で正規表現をより適切に扱う方法を学ぶのに役立つと思います。

{text1}{text2}、および{text3}は不明な文字列であることに注意してください。

部分文字列 A と B は正確にわかっています。行内で A が B の前にあることがわかっています。ただし、それらの前/間/後に何があるかはわかりません。

例 (A=ジョン、B=ティム):

(1) これ:

「私はジョンにバッグをティムに渡すように言いました。」

は次のように変更されます。

「私はティムにバッグをジョンに渡すように言いました。」

(2) これ:

「ジョンはティムに挨拶した」

は次のように変更されます。

「ティムはジョンに挨拶した。」

(3) これ:

「ジョン!h9aghagティム」

は次のように変更されます。

「ティム!アハグジョン」

4

2 に答える 2

7
>>> import re
>>> text = '{text1} {stringA} {text2} {stringB} {text3}'
>>> re.sub(r'(stringA)(.*)(stringB)', r'\3\2\1', text)
'{text1} {stringB} {text2} {stringA} {text3}'

stringAおよびを関心のある部分文字列に置き換えます。部分文字列に正規表現で特別な意味を持つ文字が含まれている可能性がある場合に備えて、それらを使用しstringBたい場合があることに注意してください。re.escape()

テストケース:

>>> stringA = 'John'
>>> stringB = 'Tim'
>>> regex = re.compile(r'(%s)(.*)(%s)' % (stringA, stringB))
>>> regex.sub(r'\3\2\1', "I told John to give the bag to Tim.")
'I told Tim to give the bag to John.'
>>> regex.sub(r'\3\2\1', "John said hello to Tim.")
'Tim said hello to John.'
>>> regex.sub(r'\3\2\1', "John!h9aghagTim")
'Tim!h9aghagJohn'
于 2012-05-29T21:43:26.917 に答える
1

取るべきアプローチは、後で参照できるようにキャプチャ グループを使用することです。

result = re.sub(r"(\{text1\}) (\{stringA\}) (\{text2\}) (\{stringB\}) (\{text3\})", r"\1 \4 \3 \2 \5", subject)

キャプチャ グループは括弧 () で識別され、\x によって Python でそれらを参照します。x はキャプチャ グループの番号です。

更新 1

あなたの例は、あなたが何を望んでいるのか、そして正規表現について現在どのように考えているのかをより明確にします。正規表現は文字のパターンに一致します。名前 (Tom、Tim、...) を交換したいので、完全な列挙によってのみ可能な名前に一致するパターンを考え出す必要があります。私の言語には(私が思うに)何千ものファーストネームがあり、そのうちのいくつかは人ではなく物を指すために使われています. その区別を行うには、正規表現ではできないコンテキストを考慮に入れる必要があります。これが理にかなっている場合はお知らせください。これ以上先に進みたい場合は重要です。

更新 2

あなたの質問は好奇心からであり、現実の問題を解決するものではないと思います。しかし、私たちがこれよりも先に進めば、あなたは遠くまで行くでしょうが、それは完璧ではありません。

正規表現

(.*)\b(John|Tim|Jo)\b(.*)\b(John|Tim|Jo)\b

と置換する

\1\4\3\2

パイソンで

result = re.sub(r"(?sm)(.*)\b(John|Tim|Jo)\b(.*)\b(John|Tim|Jo)\b", r"\1\4\3\2", subject)

単語の境界で一致が発生する必要があることを示す正規表現の \b に注意してください。これにより、Johndoe のような一致が防止されます。

また、上記の正規表現が文に対して失敗することにも注意してください

Tim は、John から Jo で終わる Jordan のいくつかのトップ レベル ドメインを購入しました。

于 2012-05-29T21:42:14.190 に答える