拆分不在Python中括号内的空格

时间:2017-02-06 14:36:19

标签: python regex

我有几个字符串,当不在括号内时,我想用空格分割。

例如

sentence = "blah (blah2 (blah3))|blah4 blah5"

应该产生

["blah", "(blah2 (blah3))|blah4", "blah5"]

我试过了:

re.split(r"\s+(?=[^()]*(?:\(|$))", sentence)

但它会产生:

['blah', '(blah2', '(blah3))|blah4', 'blah5']

3 个答案:

答案 0 :(得分:3)

如评论中所述,由于括号嵌套,使用正则表达式进行处理是不可能的。

另一种选择是使用括号中的嵌套计数进行一些好的旧字符串处理:

def parenthesis_split(sentence,separator=" ",lparen="(",rparen=")"):
    nb_brackets=0
    sentence = sentence.strip(separator) # get rid of leading/trailing seps

    l=[0]
    for i,c in enumerate(sentence):
        if c==lparen:
            nb_brackets+=1
        elif c==rparen:
            nb_brackets-=1
        elif c==separator and nb_brackets==0:
            l.append(i)
        # handle malformed string
        if nb_brackets<0:
            raise Exception("Syntax error")

    l.append(len(sentence))
    # handle missing closing parentheses
    if nb_brackets>0:
        raise Exception("Syntax error")


    return([sentence[i:j].strip(separator) for i,j in zip(l,l[1:])])

print(parenthesis_split("blah (blah2 (blah3))|blah4 blah5"))

结果:

['blah', '(blah2 (blah3))|blah4', 'blah5']

l包含发生非paren保护空间的字符串的索引。最后,通过切片列表生成数组。

注意最后的strip()来处理多个分隔符的出现,并在开始时删除将在返回的列表中创建空项的前导/尾随分隔符。

答案 1 :(得分:1)

虽然re模块确实无法处理递归,但PyPi regex module可以(在某种程度上)。不建议在生产中使用它,因为它不那么稳定。只是为了展示高级正则表达式如何工作,这里是2-regex方法:一个验证平衡括号,第二个验证令牌:

>>> import regex
>>> sentence = "blah (blah2 (blah3))|blah4 blah5"
>>> reg_extract = regex.compile(r'(?:(\((?>[^()]+|(?1))*\))|\S)+')
>>> reg_validate = regex.compile(r'^[^()]*(\((?>[^()]+|(?1))*\)[^()]*)+$')
>>> res = []
>>> if reg_validate.fullmatch(sentence):
    res = [x.group() for x in reg_extract.finditer(sentence)]

>>> print(res)
['blah', '(blah2 (blah3))|blah4', 'blah5']

提取正则表达式详细信息:匹配1次或多次

  • (\((?>[^()]+|(?1))*\)) - 捕获第1组,匹配除()以外的1个字符([^()]+)或(|){{1} } recurses整个捕获组1模式(发生递归)
  • (?1) - 或
  • | - 非空白字符

验证正则表达式详细信息

  • \S - 字符串开头
  • ^ - 除[^()]*(
  • 以外的0个字符
  • ) - 第1组捕获1次或多次:
    • ( - 打开\(符号
    • ( - 0次出现
      • (?>[^()]+|(?1))* - 除[^()]+(
      • 以外的1个字符
      • ) - 或
      • | - 子程序调用递归第1组子模式(递归)
    • (?1) - 结束\)
    • ) - 除[^()]*(
    • 以外的0个字符
  • ) - 第1组结束
  • )+ - 字符串结尾

答案 2 :(得分:-1)

这适用于贪婪的查找方法。第一个模式查找所有括号括号模式和第二个模式后的|下面的条件找到第一个模式找不到的那些单词。     (:(:(:()()(:????)))\ | [^ \ S] )|(\ W +)

在字符串中说,     &#34; blah(blah2(blah3(blah 3.5(blah 8.5))| blah4 blah5&#34;

会找到

嗒嗒

(blah2(blah3(blah 3.5(blah 8.5))| blah4

blah5

您可以点击此链接查看其工作原理。 https://regex101.com/r/dpfCWV/1