来源:
[This] is some text with [some [blocks that are nested [in a [variety] of ways]]]
结论文字:
[This] is some text with
通过查看threads at stack overflow,我认为你不能为此做正则表达式。
有一种简单的方法可以做到这一点 - >或者必须到达pyparsing(或其他解析库)?
答案 0 :(得分:5)
这是一种不需要任何依赖关系的简单方法:扫描文本并为你传递的大括号保留一个计数器。每次看到“[”时递增计数器;每次看到“]”时都会减少它。
[
s;如果它小于零,那么你就会有那么多]
s。)答案 1 :(得分:4)
将OP的示例作为规范(必须删除包含更多嵌套块的任何块),那么......:
import itertools
x = '''[This] is some text with [some [blocks that are nested [in a [variety]
of ways]]] and some [which are not], and [any [with nesting] must go] away.'''
def nonest(txt):
pieces = []
d = 0
level = []
for c in txt:
if c == '[': d += 1
level.append(d)
if c == ']': d -= 1
for k, g in itertools.groupby(zip(txt, level), lambda x: x[1]>0):
block = list(g)
if max(d for c, d in block) > 1: continue
pieces.append(''.join(c for c, d in block))
print ''.join(pieces)
nonest(x)
这会发出
[This] is some text with and some [which are not], and away.
在正常时间假设下似乎是理想的结果。
我们的想法是在level
中计算一个并行的计数列表“我们此时如何嵌套”(即到目前为止我们遇到了多少已打开且尚未关闭的括号);然后将带有level
的文本的groupby
的zip分段为具有零嵌套和嵌套的备用块> 0.对于每个块,然后计算此处的最大嵌套(对于具有零嵌套的块将保持为零 - 更一般地,它仅是整个块中嵌套级别的最大值),并且如果得到的嵌套是< = 1 ,保留相应的文本块。请注意,我们需要将组g
放入列表block
,因为我们要执行两次迭代过程(一次用于获取最大嵌套,一次用于将字符重新加入一个文本块) - 要在一次传递中执行它,我们需要在嵌套循环中保留一些辅助状态,在这种情况下这样做不太方便。
答案 2 :(得分:3)
答案 3 :(得分:3)
我编写了一个可以与expression.transformString()一起使用的解析器表达式,但是我在解析时很难区分嵌套和unnested []。最后,我不得不在transformString中打开循环并显式迭代scanString生成器。
为了解决是否应该根据原始问题包含[某些]的问题,我通过使用此字符串在末尾添加更多“unnested”文本来探讨这一点:
src = """[This] is some text with [some [blocks that are
nested [in a [variety] of ways]] in various places]"""
我的第一个解析器遵循原始问题的引导,拒绝任何包含任何嵌套的括号中的表达式。我的第二次传递采用任何括号表达式的顶级标记,并将它们放在括号中 - 我不太喜欢这个解决方案,因为我们失去了“某些”和“在不同的地方”不连续的信息。所以我接受了最后一次传递,并且必须对nestedExpr的默认行为稍作修改。请参阅以下代码:
from pyparsing import nestedExpr, ParseResults, CharsNotIn
# 1. scan the source string for nested [] exprs, and take only those that
# do not themselves contain [] exprs
out = []
last = 0
for tokens,start,end in nestedExpr("[","]").scanString(src):
out.append(src[last:start])
if not any(isinstance(tok,ParseResults) for tok in tokens[0]):
out.append(src[start:end])
last = end
out.append(src[last:])
print "".join(out)
# 2. scan the source string for nested [] exprs, and take only the toplevel
# tokens from each
out = []
last = 0
for t,s,e in nestedExpr("[","]").scanString(src):
out.append(src[last:s])
topLevel = [tok for tok in t[0] if not isinstance(tok,ParseResults)]
out.append('['+" ".join(topLevel)+']')
last = e
out.append(src[last:])
print "".join(out)
# 3. scan the source string for nested [] exprs, and take only the toplevel
# tokens from each, keeping each group separate
out = []
last = 0
for t,s,e in nestedExpr("[","]", CharsNotIn('[]')).scanString(src):
out.append(src[last:s])
for tok in t[0]:
if isinstance(tok,ParseResults): continue
out.append('['+tok.strip()+']')
last = e
out.append(src[last:])
print "".join(out)
,并提供:
[This] is some text with
[This] is some text with [some in various places]
[This] is some text with [some][in various places]
我希望其中一个接近OP的问题。但如果不出意外,我还要进一步探索nestedExpr的行为。