1

さまざまな人によって書き起こされたいくつかのテレビ エピソードを解析しています。つまり、さまざまな形式を検索する必要があります。たとえば、新しいシーンは次の 2 つの方法のいずれかで示されます。

[A coffee shop]

また

INT. Coffee shop - NIGHT

現在、これを Python の次の正規表現と照合します。

re.findall("(^\[(.+?)\]$)|(^[INTEXT]{3}\. .+?$)", text)

ここで、「テキスト」はスクリプト全体のテキストです (したがって、を使用しますfindall)。これは常に独自の行に表示されるため、^$

これは私に次のようなものを与えます:(None, None, "INT. Coffee Shop - NIGHT")例えば。

私の質問:|正規表現を作成して、表記法を使用して、2 つの複雑なパターンのいずれかを検索し、実際には必要のない部分一致を作成する方法を教えてくださいそれとももっと良い方法がありますか?

どうもありがとう。

更新: 非キャプチャ グループのアイデアを見落としていました。私が望むものを達成することができます:

"(?:^\[.+?\]$)|(?:^[INTEX]{3}\. .+?$)"

しかし、これは新たな問題を提起します。私は実際にはシーンにブラケットや INT/EXT を必要とせず、場所だけを必要とします。非キャプチャ グループ内で実際のグループを使用できると考えましたが、次のように、他の式に対してまだ空白の一致を取得しています。

import re

pattern = "(?:^\[(.+?)\]$)|(?:^[INTEX]{3}\. (.+?)$)"

examples = [                                                                                                                                                                     
    "[coffee shop]",                                                                                                                                                                 
    "INT. COFFEE SHOP - DAY",                                                                                                                                                        
    "EXT. FIELD - NIGHT",                                                                                                                                                            
    "[Hugh's aparment]"
]

for example in examples:
    print re.findall(pattern, example)


'''
[('coffee shop', '')]
[('', 'COFFEE SHOP - DAY')]
[('', 'FIELD - NIGHT')]
[("Hugh's aparment", '')]
'''

それらだけでも構いjoin()ませんが、もっと良い方法はありますか?

4

3 に答える 3

1

提供した限られた例に基づいて、角かっこにアサーションを使用するのはどうですか。

re.findall("((?<=^\[)[^[\]]+(?=\]$)|^[INTEXT]{3}\. .+?$)", text)
于 2013-03-23T13:16:44.847 に答える
1

式を 2 つだけ使用した方がよい場合があります。

patterns = [r'^\[(.+?)\]$', r'^(?:INT|EXT)\. (.+?)$']

for example in examples:
    print re.findall(patterns[0], example) or re.findall(patterns[1], example)
于 2013-03-23T17:07:27.257 に答える
0

これはあなたが望むことをするようです:

(?m)^(?=(?:\[|[INTEX]{3}\.\s+)([^\]\r\n]+))(?:\[\1\]|[INTEX]{3}\. \1)$

最初に、先読みはシーン マーカーのテキストをピークし、それをグループ #1 にキャプチャします。次に、残りの正規表現が先に進み、マーカーを含む行全体を消費します。今思うと、何も食べなくてもいいんです。これも機能します:

result = re.findall(r"(?m)^(?=(?:\[|[INTEX]{3}\.\s+)([^\]\r\n]+))", subject)

マーカー テキストは引き続きグループ #1 でキャプチャされるため、引き続き の結果に追加されfindall()ます。繰り返しますが、ここで使用する理由がわかりませんfindall()。シーン マーカーをその場で置き換えて正規化しようとしている場合は、消費するバージョンの正規表現を使用する必要があります。

また、注意して(?m)ください。あなたの例では、常に正規表現をシーン マーカーに単独で適用します。スクリプト全体からそれらを抜き出すには、MULTILINEフラグを設定して、行アンカーに変換^する必要があります。$

于 2013-03-23T18:38:39.750 に答える