![](/img/trans.png)
[英]How to split csv rows containing multiple string values based on comma but without considering comma inside curly brackets { }
[英]Split string on comma not present in round brackets or curly brackets in python
以下是我尝试用逗号分割的字符串。
如果()或{}中包含逗号,则不应拆分该字符串。
我正在使用下面的代码拆分:
现在它仅涉及(),我如何也包含{}?
import re
s = "Water,^.*f04.*&~(.*z.,*)$,Iron Oxides (CI 77491, 77492),a{3,4}"
print re.split(r',\s*(?![^()]*\))', s)
输出应为:
[Water,^.*f04.*&~(.*z.,*)$,Iron Oxides (CI 77491, 77492),a{3,4}]
假设方括号可以嵌套,那么您所用的不是普通语言。 尽管re
确实有很多扩展名,可以处理超出实际正则表达式的内容,但最好还是用一个简单的括号计数解析器来处理。
诸如此类(未经测试,但应该足够简单以理解和调试):
bracketmap = {'(': ')', '[': ']', '{': '}'}
def splitify(s):
stack = []
lastcomma = 0
for i, c in enumerate(s):
if not stack and c == ',':
yield s[lastcomma:i]
lastcomma = i+1
elif c in bracketmap:
stack.append(bracketmap[c])
elif c in ')]}':
if stack.pop() != c:
raise ValueError('unbalanced brackets')
if stack:
raise ValueError('unbalanced brackets')
if lastcomma <= len(s):
yield s[lastcomma:]
从评论中,当被问到是否可以嵌套方括号时,您说:
如果它似乎是有效的正则表达式,则可能是这样。
因此,如果该字符串实际上是正则表达式模式,则您需要做的不只是排除括号内的逗号。 例如, \\{,\\}
不是大括号内的逗号,而是完全正常的文字逗号。
显然,编写完整的regex解析器比仅计算括号对要复杂得多(尽管如果您确实需要Python re
语法,则可以使用该库进行编译,然后使用该库的调试工具扫描文字parens,而不是自己写的方法...),但是也许您可以只计算未转义的括号对而逃脱?
esc = False
for i, c in enumerate(s):
if esc:
esc = False
elif c = '\\':
esc = True
elif not stack and c == ',':
# same as before
(我在这里假设您不想将\\,
视为文字逗号。如果您这样做,那是微不足道的更改。)
使用regex
模块,允许在后面进行变长查找:
regex.split(r'(?<![({][^,]*),(?![^,]*[})])', str_)
(?<![({][^,]*)
是一个零宽度负回顾后,使确保,
不会被前面(
或{
并且没有,
在间
,
匹配文字,
(?![^,]*[})])
是一个零宽度负先行,使确保,
后面没有任何中间,
随后)
或}
例:
In [1287]: str_ = "Water,^.*f04.*&~(.*z.,*)$,Iron Oxides (CI 77491, 77492),a{3,4}"
In [1288]: regex.split(r'(?<![({][^,]*),(?![^,]*[})])', str_)
Out[1288]: ['Water', '^.*f04.*&~(.*z.,*)$', 'Iron Oxides (CI 77491, 77492)', 'a{3,4}']
限制:
[({]
匹配任何(
/ {
和[})]
匹配)
/ }
任何内容,因此,例如当子字符串以(
并以}
结尾或以其他方式出现时,这可能会导致错误
不适用于嵌套的括号/括号
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.