我需要分割一个字符串,如:
aaaa b aaaa {aaa b aaa} aaa b aaa
由'b'元素,但不是括号中的部分。这不是html或xml,所以我没有尝试任何模块。
'aaa'表示任意文本。
结果如下:
['aaa', 'b', 'aaaa {aaa b aaa} aaa', 'b', 'aaa']
仍然无法弄清楚正则表达式。
我理解,'lookbehind'构造(?<!...)
不起作用,因为大括号中的文本可能有不同的长度。
我不得不尝试[^{]*?(b)[^}]*?
公式,但它仍然在括号中捕获“b”。
想不出别的什么。请帮忙。
UPD:我解析了一个很长的行(包括EOL),因此无法在行的开头或结尾匹配“b”似乎不是问题(“b”不存在)。在re.compile()中添加re.S(点)标志应该可以解决问题。
答案 0 :(得分:2)
答案 1 :(得分:1)
由于要求不是很清楚,我在这个解决方案中做了很多假设,我甚至不知道它是否适用于你的输入:
>>> re.split(r"(?:^|\s*\b)(b)(?:\s+(?![^{}]*})|$)", "aaaa b aaaa {aaa b aaa} aaa b aaa")
['aaaa', 'b', 'aaaa {aaa b aaa} aaa', 'b', 'aaa']
>>> re.split(r"(?:^|\s*\b)(b)(?:\s+(?![^{}]*})|$)", "b aaaa b b aaaa {aaa b aaa} aaa b aaa b")
['', 'b', 'aaaa', 'b', '', 'b', 'aaaa {aaa b aaa} aaa', 'b', 'aaa', 'b', '']
我只是确保用作分隔符的b
后面没有&#34;普通文本&#34; (或者更准确地说,任何不是大括号[^{}]
的字符)然后是一个结束的大括号}
。
我捕获(b)
,因此它出现在结果数组中。
为了照顾周围的空间,我需要消耗周围的空间(如果有的话),这就是上面正则表达式复杂化的原因。
这是我的原始(更简单)解决方案,适用于您的输入:
>>> re.split(r"\s+(b)\s+(?![^{}]*})", "aaaa b aaaa {aaa b aaa} aaa b aaa")
['aaaa', 'b', 'aaaa {aaa b aaa} aaa', 'b', 'aaa']
但是,如果b
位于字符串的开头,字符串的结尾或者有2个连续的b
条目,则会失败:
>>> re.split(r"\s+(b)\s+(?![^{}]*})", "b aaaa b b aaaa {aaa b aaa} aaa b aaa b")
['b aaaa', 'b', 'b aaaa {aaa b aaa} aaa', 'b', 'aaa b']
答案 2 :(得分:0)
很难通过默认的re
模块找出答案。所以我使用了外部regex
模块。
>>> s = "aaaa b aaaa {aaa b aaa} aaa b aaa"
>>> regex.split(r'\s(?=b(?:\s|$)(?![^{}]*}))|(?<=(?:^|\s)b)\s(?![^{}]*})', s)
['aaaa', 'b', 'aaaa {aaa b aaa} aaa', 'b', 'aaa']
>>> s = "b a bbb b bbb bbb"
>>> regex.split(r'\s(?=b(?:\s|$)(?![^{}]*}))|(?<=(?:^|\s)b)\s(?![^{}]*})', s)
['b', 'a bbb', 'b', 'bbb bbb']
答案 3 :(得分:0)
您也可以预先使用。
>>> a = 'aaaa b aaaa {aaa b aaa} aaa b aaa'
>>> re.split("\s*(b)\s*(?![\w ]*})", a)
['aaaa', 'b', 'aaaa {aaa b aaa} aaa', 'b', 'aaa']
在这种情况下,如果你不关心额外的空白,它就有效。
答案 4 :(得分:-1)
只要没有嵌套大括号,那就简单了:
>>> x="aaaa b aaaa {aaa b aaa} aaa b aaa"
>>> re.findall(r'\S+(?:\s*\{.*?\}\s*)?\S*',x)
['aaaa', 'b', 'aaaa {aaa b aaa} aaa', 'b', 'aaa']