我正在尝试解析PDF以从中提取文本(请不要建议任何库来执行此操作,因为这是学习格式的一部分。)
我已经处理了缩小它以使用字母数字格式。我现在需要从文本块中提取文本
所以,我当前的模式是BT.*?\((.*?)\).*?ET
(设置了DOTMATCHALL),以匹配以下内容:
BT
/F13 12 Tf
288 720 Td
(ABC) Tj
ET
我想要的唯一一点就是方括号中的文字ABC 上面的格式只是为了清楚地看到。在缩小的文本中,它可能全部在一行中,也可能不是。没有保证BT / ET将在一条线的起点。在括号内部分之前/之后可能有空格和文字,可能没有。但是,每个BT / ET块只有一个括号内的部分。
上面的模式有效,但实际上很慢,我认为这是因为正则表达式库无法匹配BT和(ABC)之间的文本多次匹配的模式。
正则表达式是预编译的,试图加快速度,但似乎可以忽略不计。
我怎样才能加快速度?
答案 0 :(得分:3)
文档中可能出现多少块?
正常缓慢的正则表达式执行是灾难性回溯的结果,如下所述:http://www.regular-expressions.info/catastrophic.html
我不知道您正在使用哪种正则表达式技术,但您可以尝试使用外观断言,如下所述: http://www.regular-expressions.info/lookaround.html
这些允许您首先匹配您想要的内容,ABC
在括号内,然后验证它前面有一些值,后跟一些其他值。
答案 1 :(得分:1)
你确定正则表达式是否正确并将ABC拉出来作为匹配?这是什么语言的正则表达式引擎?使用我的正则表达式调试器显示:
"BT.*?((.*?)).*?ET"
没有提取ABC,实际上必须找到字符串'ET'然后回溯以找到其他所有内容。
"BT.*?\\((.*?)\\).*?ET"
按预期工作,从左到右单次传递。
答案 2 :(得分:0)
您不能只使用正则表达式解析PDF来提取文本。在大多数情况下,文本内部压缩二进制blob或编码。带有这样的文字的PDF是非常例外的。
答案 3 :(得分:0)
确切的答案还没有足够的信息 - 或许你假设我们比你更了解PDF。这些BT...ET
部分中是否始终包含带括号的块?总是只有其中一个吗? BT
或ET
始终位于一行的开头吗?如果是这样,我会建议
(?m)^BT[^()]*\((.*?)\)[^()]*?^ET
如果我知道PDF如何代表字面括号,我可能会想出更高效的东西。
编辑:根据PDF规范,字面括号必须使用反斜杠进行转义,并且还有许多其他反斜杠转义序列。所以试试这个:(?s)\bBT\b[^()]*\(((?:[^()\\]*(?:\\.[^()\\]*)*))\)
此部分 - [^()\\]*(?:\\.[^()\\]*)*
- 匹配可能包含转义字符(包括parens)的文本块,但不包含未转义的parens。我知道它看起来很难看,但它是最有效的方式,因为Python不支持原子组或占有量词。
(?s)
允许.
匹配换行符,而\bBT\b
可确保BT
不属于较长的“单词”。我有理由相信这就是我需要匹配所有实际文本内容的所有内容,因此我不会在收尾后对这些内容进行匹配。
答案 4 :(得分: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
答案 5 :(得分:0)
由于BT
和ET
之间只有一个括号内的表达式,因此您可以尝试使用以下正则表达式来提高速度:
r"(?s)\bBT\b[^(]*\(([^)]*)\).*?\bET\b"