【问题标题】:Finding a string of varying length within parentheses that contain parentheses在包含括号的括号内查找长度不等的字符串
【发布时间】:2014-01-08 07:08:22
【问题描述】:

我想输入一个具有某种形式的字符串输入(可能会有所不同)

aString = "foo1(bar1(foo2bar2)) foo3(bar3)"

我想使用某种会返回的正则表达式

[[foo1, (bar1(foo2bar2))], [foo3, (bar3)]]

实际的字符串由字母、数字、空格和括号组成。我首先使用aString.split() 将其按空格分开,然后用外括号将每个部分分开。我到目前为止是这样的:

import re

aString = "foo1(bar1(foo2bar2)) foo3(bar3)"
aList = aString.split()
newList = []
for part in aList:
    index1 = part.find('(')
    index2 = part.rfind(')')
    aLen = index2 - index1 - 1
    prog = re.compile(r'(\(.{,aLen}\))')
    newList.append(prog.split(part))

print newList

返回这个:

[['foo1(bar1(foo2bar2))'], ['foo3(bar3)']]

我对这种形式的正则表达式的理解是,. 将匹配所有字符串,{,aLen} 将匹配前一个正则表达式的零和 aLen 重复,在本例中为 . 或所有字符串。但是,正如您所看到的,它似乎并没有这样做,因为正在运行

newList.append(prog.match(part)) 而不是newList.append(prog.split(part))

返回[None, None]

我在正则表达式方面没有太多经验,所以我肯定会误解不同的正则表达式的含义或它们的工作原理。

任何帮助将不胜感激!

【问题讨论】:

  • 那么你想要的是一个接受 Fname(args) 并将其转换为 [[fname, args],[other_fname, [nested_fname, args]] 等...] 的东西?跨度>
  • @OmegaOuter 否。我想采用上面显示的形式的字符串,或者在下面的答案的 cmets 中,并返回所有括号的内部而不删除括号。括号的位置和数量会有所不同(它们总是会打开和关闭),括号之间区域的内容/长度也会有所不同。
  • 嗯,我确实阅读了下面的 cmets,我真诚地预期两者的预期结果是不同的。在原始问题中,您不执行嵌套遍历,就像在下面的问题中那样,在第一个问题中,您可能会采用任意数量的表达式。我认为您应该编辑原始问题以解决您正在寻找的确切行为。

标签: python regex string python-2.7


【解决方案1】:

在这种特殊情况下,您可能完全可以使用正则表达式。如果您只需要执行一次此拆分操作,您可以使用string.partition 简单地按第一次出现的外括号进行拆分。

def parse(string):
    front, paren, back = string.partition('(')
    return [front, paren + back]

def parse_many(string):
    return [parse(s) for s in string.split()]

aString = "foo1(bar1(foo2bar2)) foo3(bar3)"
print parse_many(aString)

但是,如果您的输入比这更复杂(如果您尝试实现某种解析器),那么您可能需要考虑使用实际的解析库,例如 pyparsing。

如果您确实想使用正则表达式,那么以下应该可以工作:

import re

aString = "foo1(bar1(foo2bar2)) foo3(bar3)"
aList = aString.split()
newList = []
for part in aList:
    prog = re.compile(r'([a-zA-Z0-9]*)(.*)')
    newList.append(prog.split(part)[1:3])

print newList

在这种情况下,正则表达式首先匹配任何字母和数字序列,然后再匹配其他所有内容。请注意,此正则表达式不会尝试验证初始单词后面的字符串是否包含在括号中,也不会尝试验证括号的数量是否正确匹配。结果,正则表达式可能最终过于宽松,并匹配无效的字符串,具体取决于您的特定用例。

【讨论】:

  • 好吧,输入字符串可能会变得相当复杂,某种形式的 foo1bar1(foo2bar2(foo3bar3(foo4bar4(foo5bar5))))foo1bar1(foo2bar2(foo3bar3(foo4bar4)foo5bar5(foo6bar6))) 或其他类似的形式。我仍然想像以前一样分隔字符串,所以在第一种情况下[foo1bar1, [(foo2bar2, [(foo3bar3, [(foo4bar4, [(foo5bar5)], ')'], ')'], ')'], ')']。在这种情况下,您会推荐使用解析库或某种使用正则表达式的递归函数吗?
  • @Dannnno -- 会有逗号吗?例如,字符串是否会类似于f1(a1, f2(a2, a3), f4(f5(a1)))
  • @Dannnno -- 是否要求您在最终输出中保留括号,在那个精确的配置中,或者如果它们被删除是否可以接受?
  • 说实话我不确定。我实际上还没有编写处理括号的代码部分。把它们去掉可能就好了。
猜你喜欢
  • 2019-11-25
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多