1

我正在解析一些由不同人转录的电视剧集,这意味着我需要搜索各种格式。例如,新场景以以下两种方式之一表示:

[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()使用它们,但有更好的方法吗?

4

3 回答 3

1

根据您提供的有限示例,如何为括号使用断言:

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

最好只使用两个表达式。

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 回答