一尘不染

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

python

我得到了这样的格式的字符串:

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

因此从根本上讲,它是演员姓名的列表(可选地,后面是他们在括号中的角色)。角色本身可以包含逗号(演员的名字不能,我强烈希望如此)。

我的目标是将此字符串分成成对的列表- (actor name, actor role)

一个明显的解决方案是遍历每个字符,检查是否出现'('')'','在出现逗号时将其拆分。但这似乎有点沉重…

我正在考虑使用正则表达式拆分它:首先用括号将字符串拆分:

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', '']

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

是否有任何更简单/更好的方法来执行此操作,而只需一个正则表达式或一段不错的代码?


阅读 179

收藏
2020-12-20

共1个答案

一尘不染

一种方法是findall与正则表达式一起使用,该正则表达式贪婪地匹配可以在分隔符之间使用的内容。例如:

>>> 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)']

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

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

关于此方法的一个怪癖是将相邻的分隔符视为单个分隔符。也就是说,您不会看到一个空字符串。根据您的用例,这可能是错误或功能。

另外请注意,正则表达式是 适合在那里筑巢是一种可能性的情况下。因此,例如,这将错误地拆分:

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

如果您需要处理嵌套,则最好的选择是将字符串分成括号,逗号和其他所有内容(本质上是对其进行标记化-
这部分仍可以使用正则表达式来完成),然后遍历这些标记重新组合字段,并保持跟踪嵌套级别(此嵌套级别是正则表达式无法自行执行的操作)。

2020-12-20