如何使用正则表达式提取电影剧本中的发言者姓名及对应台词
可用正则及实现代码
import re # 核心匹配正则 pattern = r'^([A-Z][A-Z\s]+)$\s*?(.*?)\s*?(?=^[A-Z][A-Z\s]+$|\Z)' # 读取本地剧本文件 with open('script.txt', 'r', encoding='utf-8') as f: content = f.read() # 匹配所有发言块,必须指定两个标志位 matches = re.findall(pattern, content, flags=re.MULTILINE | re.DOTALL) # 清洗台词、过滤动作描述、格式化空格 result = [] for speaker, raw_line in matches: # 过滤独立动作行:行首大写且第二个字符为小写字母的行 lines = raw_line.split('\n') valid_lines = [] for l in lines: l_stripped = l.strip() if not l_stripped: continue # 排除动作行,单个大写字母开头的台词行不会被误删 if len(l_stripped) < 2 or not (l_stripped[0].isupper() and l_stripped[1].islower()): valid_lines.append(l_stripped) # 合并多行台词为单行 cleaned_line = ' '.join(valid_lines) if cleaned_line: result.append({'speaker_name': speaker.strip(), 'line_spoken': cleaned_line})
正则逻辑说明
re.MULTILINE标志:让^和$匹配每一行的开头和结尾,而非整个文本的首尾,适配剧本里发言者姓名单独占一行的格式re.DOTALL标志:让通配符.可以匹配换行符,适配超过2行的长台词场景,不需要硬编码台词行数- 分组1
^([A-Z][A-Z\s]+)$:匹配整行仅包含大写字母和空格的内容,也就是标准剧本格式的发言者姓名,同时支持带空格的复合姓名(如SOCIAL WORKER) \s*?:非贪婪匹配姓名行后的所有空白字符(包括换行、空行),跳过姓名和台词之间的空行- 分组2
(.*?):非贪婪匹配所有内容,直到触发终止条件 - 正向先行断言
(?=^[A-Z][A-Z\s]+$|\Z):设置匹配终止规则,要么遇到下一个发言者姓名行,要么到整个文本的末尾,自动识别台词结束位置
额外清洗逻辑说明
匹配得到的原始台词内容可能夹杂独立的动作描述行,这类行的通用特征是行首第一个字符大写、第二个字符为小写字母,和全大写的姓名行、首字母为单个大写字母开头的台词行(如I ...)可以有效区分。如果存在台词行首为短词(如No、Yes)导致误过滤的情况,可调整判断逻辑,比如增加行长度阈值、补充短词白名单即可。
内容的提问来源于stack exchange,提问作者Sreyan Ghosh
相关产品推荐
相关产品推荐

