如何用括号外的逗号分隔字符串?

2024-09-27 07:32:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一系列这样的格式:

"Wilbur Smith (Billy, son of John), Eddie Murphy (John), Elvis Presley, Jane Doe (Jane Doe)"

所以基本上是演员的名字列表(可以选择在括号中后跟他们的角色)。角色本身可以包含逗号(我强烈希望演员的名字不能包含逗号)。

我的目标是把这个字符串分成一个成对的列表-(actor name, actor role)

一个明显的解决方案是遍历每个字符,检查是否出现'('')'','并在出现外部逗号时将其拆分。但这看起来有点重。。。

我正在考虑使用regexp拆分它:首先用括号拆分字符串:

import re
x = "Wilbur Smith (Billy, son of John), Eddie Murphy (John), Elvis Presley, Jane Doe (Jane Doe)"
s = re.split(r'[()]', x) 
# ['Wilbur Smith ', 'Billy, son of John', ', Eddie Murphy ', 'John', ', Elvis Presley, Jane Doe ', 'Jane Doe', '']

这里奇怪的元素是演员的名字,甚至是角色。然后,我可以用逗号分隔名称,并以某种方式提取名称-角色对。但这似乎比我的第一个方法更糟。

有没有更简单/更好的方法可以做到这一点,要么使用一个regexp,要么使用一段漂亮的代码?


Tags: of角色johnsmith逗号eddiedoeelvis
3条回答

我认为最好的方法是使用python的内置csv模块。

因为csv模块仅allows一个字符quotechar,所以需要对输入进行替换,以将()转换为|"之类的内容。然后确定你用的是一种合适的方言,然后你就走了。

s = re.split(r',\s*(?=[^)]*(?:\(|$))', x) 

lookahead将所有内容都匹配到下一个左括号或字符串末尾,iff之间没有右括号。确保逗号不在一组圆括号内。

一种方法是对regex使用findall,该regex贪婪地匹配分隔符之间的内容。例如:

>>> s = "Wilbur Smith (Billy, son of John), Eddie Murphy (John), Elvis Presley, Jane Doe (Jane Doe)"
>>> r = re.compile(r'(?:[^,(]|\([^)]*\))+')
>>> r.findall(s)
['Wilbur Smith (Billy, son of John)', ' Eddie Murphy (John)', ' Elvis Presley', ' Jane Doe (Jane Doe)']

上面的正则表达式匹配一个或多个:

  • 非逗号、非开放paren字符
  • 以开放paren开头的字符串,包含0个或多个非封闭paren,然后是封闭paren

这种方法的一个怪癖是相邻的分离器被视为一个单独的分离器。也就是说,你不会看到空字符串。这可能是一个bug或特性,具体取决于您的用例。

还要注意,正则表达式适合可能嵌套的情况。例如,这将不正确地拆分:

"Wilbur Smith (son of John (Johnny, son of James), aka Billy), Eddie Murphy (John)"

如果您需要处理嵌套问题,最好的办法是将字符串划分为paren、逗号和其他所有内容(本质上是标记化它——这一部分仍然可以用正则表达式来完成),然后遍历那些重新组合字段的标记,在运行时跟踪嵌套级别(这种跟踪嵌套级别的方式是regex无法独立完成的)。

相关问题 更多 >

    热门问题