删除所有嵌套块,而只留下非嵌套块通过Python
[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(或其他解析库)?
以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.
其中normatime假设下,似乎是所期望的结果。
这个想法是在level
中计算一个并行的计数列表“我们在这一点上是多么嵌套”(即,迄今为止我们遇到了多少已打开和尚未关闭的括号);然后将level
的文本与文本groupby
一起拆分为零嵌套和嵌套> 0的替代块。对于每个块,计算此处的最大嵌套(对于嵌套为零的块将保持为零) - 更一般地说,它是只是整个块中嵌套层次的最大值),如果产生的嵌套为< = 1,则保留相应的文本块。请注意,我们需要将组g
放入列表block
中,因为我们要执行两次迭代过程(一次获得最大嵌套,一次将字符重新加入到文本块中) - 在单次传递中需要在嵌套循环中保留一些辅助状态,这在这种情况下不太方便。
我需要一些时间来消化这个答案中的信息。但有一点可以肯定,它的效果非常出色。 – torger 2009-12-28 01:44:07
下面是一个简单的方法,不需要任何依赖关系:扫描文本并为您传递的大括号保留一个计数器。每当你看到一个“[”;每次看到“]”时减少它。
- 只要计数器为零或一个,将您看到的文本放到输出字符串中。
- 否则,您处于嵌套块中,因此不要将文本放到输出字符串中。
- 如果计数器未完成为零,则该字符串格式不正确;你有不同数量的开合支撑。 (如果是大于零,你有很多多余的
[
秒;如果是小于零,你有很多多余的]
秒)
+1这正是我要说的。 – 2009-12-27 08:19:56
但在他的例子中,''有些'会被放在输出字符串中使用你的方法。如果在此块中没有更高级别,则必须保存出现在“级别1”的文本,并仅将其放入输出字符串中。 – 2009-12-27 08:50:27
我不确定这个例子是不正确的,因为这看起来像一个错字。该块不是“嵌套”,直到内部支架。但如果情况并非如此,那么你只需要在遇到“]”时写入输出(在这种情况下,如果计数器太深,或者如果计数器没有问题,则丢弃)或者结束串。 – 2009-12-27 09:29:17
我在写一个可以与expression.transformString()一起使用的解析器表达式的过程中花费了一些时间,但是我在解析时很难区分嵌套和非嵌入[]。最后,我不得不在transformString中打开循环,并显式地遍历scanString生成器。
为了解决是否[某些]应在原有基础上的问题被列入与否,我探讨过这个由末,加入更多的“嵌套的”文本使用该字符串的问题:
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的行为。
我认为你的例子有误。它不应该[这]是一些文字与[一些]?紧跟在“with”之后的部分中的文本不是嵌套的。 – 2009-12-27 08:14:47
+1之前你问。 – Kobi 2009-12-27 10:20:19