正则匹配非常慢

2 投票
6 回答
1820 浏览
提问于 2025-04-15 21:08

我正在尝试解析一个PDF文件,以提取其中的文本(请不要建议任何库来完成这个,因为这是我学习格式的一部分)。
我已经处理过解压缩,将其转换为字母数字格式。现在我需要从文本块中提取文本。
所以,我目前使用的模式是 BT.*?\((.*?)\).*?ET(设置了DOTMATCHALL),用来匹配类似下面的内容:

BT
   /F13 12 Tf
   288 720 Td
   (ABC) Tj
ET

我只想要括号中的文本ABC。
上面的格式只是为了让它更清晰。在解压后的文本中,可能会全部在一行,也可能不会。BT和ET不一定会在行的开头。括号前后可能有空格和文本,也可能没有。不过,每个BT/ET块中只会有一个括号部分。

这个模式可以用,但速度很慢,我猜是因为正则表达式库在多次匹配BT和(ABC)之间的文本时效率不高。
我已经尝试预编译正则表达式来加快速度,但似乎效果不明显。

我该如何加快这个过程呢?

6 个回答

1

你确定这个正则表达式是正确的吗?它能找到ABC这个匹配项吗?你用的是哪种编程语言的正则表达式引擎?我用我的正则表达式调试工具查看了一下:

"BT.*?((.*?)).*?ET" 这个表达式并不能找到ABC,实际上它必须先找到字符串'ET',然后再回溯去找其他的内容。

"BT.*?\\((.*?)\\).*?ET" 这个表达式则能按预期工作,从左到右只需一次扫描就能找到结果。

4

在一个文档中,这些块可能会出现多少次呢?

通常,正则表达式执行得很慢是因为出现了灾难性的回溯,具体情况可以参考这里:http://www.regular-expressions.info/catastrophic.html

我不知道你使用的正则表达式技术是什么,但你可以尝试使用前后查找断言,具体说明可以查看这里: http://www.regular-expressions.info/lookaround.html

这些可以让你先匹配你想要的内容,比如把ABC放在括号里,然后再验证它前面和后面是否有特定的值。

0

这里有一个不使用正则表达式的例子。它是用Python内部功能进行简单的字符串解析。

>>> xtract="""
... BT
...    /F13 12 Tf
...    288 720 Td
...    (ABC) Tj
... ET
...
... """
>>> for chunk in xtract.split("ET"):
...     if "BT" in chunk:
...         for brace in chunk.split(")"):
...             if "(" in brace:
...                  print brace[brace.find("(")+1:]
...
ABC

撰写回答