首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用逗号分隔字符串,但在括号环境中除外

用逗号分隔字符串,但在括号环境中除外
EN

Stack Overflow用户
提问于 2014-11-07 19:44:47
回答 3查看 6.1K关注 0票数 11

我想在Python的逗号处拆分一个Python多行字符串,除非逗号位于括号内的表达式中。例如,绳子

代码语言:javascript
复制
{J. Doe, R. Starr}, {Lorem
{i}psum dolor }, Dol. sit., am. et.

分拆成

代码语言:javascript
复制
['{J. Doe, R. Starr}', '{Lorem\n{i}psum dolor }', 'Dol. sit.', 'am. et.']

这涉及到括号匹配,因此可能regexes在这里没有帮助。PyParsingcommaSeparatedList,除了引用的(")环境是受保护的,而不是{}-delimited环境,它几乎可以满足我的需要。

有什么暗示吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-11-07 19:52:08

编写您自己的自定义拆分函数:

代码语言:javascript
复制
 input_string = """{J. Doe, R. Starr}, {Lorem
 {i}psum dolor }, Dol. sit., am. et."""


 expected = ['{J. Doe, R. Starr}', '{Lorem\n{i}psum dolor }', 'Dol. sit.', 'am. et.']

 def split(s):
     parts = []
     bracket_level = 0
     current = []
     # trick to remove special-case of trailing chars
     for c in (s + ","):
         if c == "," and bracket_level == 0:
             parts.append("".join(current))
             current = []
         else:
             if c == "{":
                 bracket_level += 1
             elif c == "}":
                 bracket_level -= 1
             current.append(c)
     return parts

 assert split(input_string), expected
票数 16
EN

Stack Overflow用户

发布于 2014-11-07 20:00:12

在这种情况下,您可以使用re.split

代码语言:javascript
复制
>>> from re import split
>>> data = '''\
... {J. Doe, R. Starr}, {Lorem
... {i}psum dolor }, Dol. sit., am. et.'''
>>> split(',\s*(?![^{}]*\})', data)
['{J. Doe, R. Starr}', '{Lorem\n{i}psum dolor }', 'Dol. sit.', 'am. et.']
>>>

下面是Regex模式匹配的说明:

代码语言:javascript
复制
,       # Matches ,
\s*     # Matches zero or more whitespace characters
(?!     # Starts a negative look-ahead assertion
[^{}]*  # Matches zero or more characters that are not { or }
\}      # Matches }
)       # Closes the look-ahead assertion
票数 8
EN

Stack Overflow用户

发布于 2016-03-31 08:00:58

卢卡斯·特兹涅夫斯基的评论实际上可以在PyPi正则模中使用(我刚刚用一个编号的组替换了命名组,以使它更短):

代码语言:javascript
复制
>>> import regex
>>> r = regex.compile(r'({(?:[^{}]++|\g<1>)*})(*SKIP)(*FAIL)|\s*,\s*')
>>> s = """{J. Doe, R. Starr}, {Lorem
{i}psum dolor }, Dol. sit., am. et."""
>>> print(r.split(s))
['{J. Doe, R. Starr}', None, '{Lorem\n{i}psum dolor }', None, 'Dol. sit.', None, 'am. et.']

模式- ({(?:[^{}]++|\g<1>)*})(*SKIP)(*FAIL) -匹配{...{...{}...}...}类结构(因为{匹配{(?:[^{}]++|\g<1>)*匹配0+出现的2种替代: 1)除{} ( [^{}]++)以外的任何1+字符,2)匹配整个({(?:[^{}]++|\g<1>)*})子模式的文本)。(*SKIP)(*FAIL)谓词使引擎忽略匹配缓冲区中的整个匹配值,因此,将索引移到匹配的末尾,不保存返回的任何内容(我们“跳过”了匹配的内容)。

\s*,\s*匹配一个用0+空格括起来的逗号。

出现None值是因为第一个分支中有一个捕获组,在第二个分支匹配时为空。我们需要在第一个可供选择的分支中使用一个捕获组进行递归。若要删除空元素,请使用“理解”:

代码语言:javascript
复制
>>> print([x for x in r.split(s) if x])
['{J. Doe, R. Starr}', '{Lorem\n{i}psum dolor }', 'Dol. sit.', 'am. et.']
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26808913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档