string = "Will Ferrell (Nick Halsey), Rebecca Hall (Samantha), Michael Pena (Frank Garcia)"
import re
pat = re.compile(r'([^(]+)\s*\(([^)]+)\)\s*(?:,\s*|$)')
lst = [(t[0].strip(), t[1].strip()) for t in pat.findall(string)]
编译的模式有点棘手。这是一条生硬的线,让反斜杠不那么疯狂。意思是:启动一个匹配组;匹配任何不是“(”字符的内容,只要它至少是一次,就可以匹配任意次数;关闭匹配组;匹配一个文本“(”字符;启动另一个匹配组;匹配任何不是“)”字符的内容,只要它至少是一次,就可以匹配任意次数;关闭匹配组;匹配一个文本“)”字符;然后匹配任何空格(包括无空格);然后是非常棘手的事情。真正棘手的部分是不构成匹配组的分组。它不是以“(”开头,而是以“(?”结尾?:“然后再以“)”结尾。我使用了这个分组,这样我就可以在其中放置一个竖线来允许两种不同的模式:要么是逗号匹配,后跟任意数量的空格,要么是到达了行的末尾('$'字符)。
然后我使用pat.findall()查找模式匹配的string中的所有位置;它自动返回元组。我把它放在一个列表理解中,并对每个项目调用.strip(),以清除空白。
当然,我们可以使正则表达式更加复杂,并让它返回已经去掉空白的名称。不过,正则表达式会变得非常毛茸茸的