2

我不确定正则表达式是最好的方法,但它似乎非常适合。本质上,我目前正在使用 pdfminer 解析一些 pdf,缺点是这些 pdf 是导出的 powerpoint 幻灯片,这意味着所有动画都显示为相当长的字符串副本。理想情况下,我只想要这些字符串中的每一个的副本,而不是动画的每个阶段的副本。现在我正在使用的当前正则表达式模式是这样的:

re.sub(r"([\w^\w]{10,})\1{1,}", "\1", string)

但由于某种原因,这似乎并没有改变输入字符串。我觉得出于某种原因 python 无法识别捕获组,但我不确定如何解决该问题。任何想法表示赞赏。

例子:

I would like this
text to be

reduced
I would like this
text to be

reduced

输出:

I would like this
text to be

reduced

更新:为了通过抽水引理,我必须明确断言所有重复项都是相邻的。这是以前暗示的,但我现在明确表示以确保解决方案是可能的。

4

1 回答 1

3

正则表达式不是该任务的正确工具。它们基于上下文无关语言的理论,如果字符串包含重复项并删除重复项,它们将无法匹配。您可能会发现有关该主题的有趣的自动机和正则表达式课程。

我认为 Josay 的建议既高效又聪明,但我认为我得到了一个更简单和 Pythonic 的解决方案,尽管它有其局限性。您可以将字符串拆分为行列表,并将其通过 a 传递set()

>>> s = """I would like this
... text to be
... 
... reduced
... I would like this
... text to be
... 
... reduced"""
>>> print "\n".join(set(s.splitlines()))
I would like this

text to be
reduced
>>>

该解决方案的唯一问题是您将失去行的原始顺序(该示例是一个很好的反例)。此外,如果您在两种不同的上下文中使用同一行,那么您最终将只有一行。

  • 要解决第一个问题,您可能必须再次遍历原始字符串以将该集合重新排序,或者简单地使用有序集合
  • 如果您有任何符号分隔每张幻灯片,它将帮助您仅合并重复项,从而解决该解决方案的第二个问题。

否则将需要更复杂的算法,因此您可以考虑邻近度和上下文。为此,后缀树可能是一个好主意,并且为此有 python 库(参见那个 SO answer)。

编辑:

使用您的算法,我可以通过添加对多行的支持并在您的文本匹配中添加空格和结束线来使其工作:

>>> re.match(r"([\w \n]+)\n\1", string, re.MULTILINE).groups()
('I would like this\ntext to be\n\nreduced',)

虽然,这个\1符号不是匹配部分的正则表达式语法,而是一个扩展。但是这里已经很晚了,我可能完全错了。也许我应该重读那些课程?:-)

我猜想正则表达式引擎的下推自动机能够推送匹配,因为它只是一个长的多行字符串,它可以弹出匹配。虽然我希望它有副作用......

于 2013-06-19T22:40:44.747 回答