簡體   English   中英

在Python中搜索兩個復雜的正則表達式模式之一,而不創建子匹配項

[英]Searching for one of two complexish regex patterns in Python without creating submatches

我正在解析一些由不同人錄制的電視劇集,這意味着我需要搜索多種格式。 例如,以兩種方式之一指示新場景:

[A coffee shop]

要么

INT. Coffee shop - NIGHT

現在,我將其與Python中的以下正則表達式進行匹配:

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

其中“文本”是整個腳本的文本(因此使用findall )。 它總是出現在自己的行上,因此^$

例如,這給了我類似的東西:( (None, None, "INT. Coffee Shop - NIGHT")

我的問題:如何使用|構造正則表達式來搜索兩個復雜模式之一? 符號, 沒有創造,你真的不希望子匹配? 或者,還有更好的方法?

非常感謝。

更新 :我忽略了不捕獲組的想法。 我可以完成我想要的:

"(?:^\[.+?\]$)|(?:^[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()它們,但是有更好的方法嗎?

根據您提供的有限示例,如何在方括號中使用斷言:

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

僅使用兩個表達式可能會更好。

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

for example in examples:
    print re.findall(patterns[0], example) or re.findall(patterns[1], example)

這似乎可以滿足您的要求:

(?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標志,將^$變成行錨。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM