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

2024-04-27 14:23:03 发布

您现在位置:Python中文网/ 问答频道 /正文

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

例如

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

应该产生

^{pr2}$

我试过:

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

但它产生了:

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

Tags: 字符串resentence括号splitblah空格pr2
2条回答

正如评论中所说,由于括号嵌套,使用正则表达式是不可能的。在

另一种方法是使用括号上的嵌套计数进行一些良好的旧字符串处理:

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"))

结果:

^{pr2}$

l包含出现非paren受保护空间的字符串的索引。最后,通过对列表进行切片来生成数组。在

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

虽然re模块不能处理递归,但是PyPi ^{} 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']

提取regex details:匹配

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

验证正则表达式详细信息

  • ^-字符串的开头
  • [^()]*-0+个字符,而不是(和{}
  • (-第1组捕捉到1次或多次出现:
    • \(-打开(符号
    • (?>[^()]+|(?1))*-0+次
      • [^()]+-1+个字符,而不是(和{}
      • |-或
      • (?1)-子例程调用递归组1子模式(递归)
    • \)-结束语)
    • [^()]*-0+个字符,而不是(和{}
  • )+-第1组结束
  • $-字符串结尾

相关问题 更多 >