使用 iText 解析 PDF 文档后反转希伯来语或数字
Reversed Hebrew or numbers after using iText to parse a PDF document
我正在使用 iText5 解析主要用希伯来语编写的 pdf。
要提取文本,我使用 PdfTextExtractor.getTextFromPage
。我没有找到更改库中编码的方法,文本显示为乱码。
我试过这样修复编码:
new String(pdfPage.getBytes(Charset1), Charset2)
.
我使用 Charset.availableCharsets()
遍历了所有可能的字符集,其中很少有人给了我希伯来语而不是乱码但相反。
现在我以为我可以逐行反转文本,但是希伯来语是从右到左,数字和英语是从左到右。因此,如果我反转行,它会修复希伯来语但会破坏 numbers/English.
示例:
PdfTextExtractor.getTextFromPage
returns 87.55 úåáééçúä ééåëéð ë"äñ
new String(text.getBytes(Charset.forName("ISO-8859-1")), Charset.forName("windows-1255"))
returns 87.55 תובייחתה ייוכינ כ"הס
如果我反转这个然后我得到 סה"כ ניכויי התחייבות 55.78
数字应该是 87.55
而不是 55.78
我找到的唯一解决方案是将其拆分为希伯来语和其余部分 (English/numbers),仅反转希伯来语部分,然后将其合并回去。
没有更简单的解决方案吗?我觉得我在 encoding/RTL
中遗漏了一些东西
I cant share the document I'm working on because it contains PII. But after searching Goole for pdf with gibberish, I found this document - the last paragraph of the document has exactly the same problem I have in my documents.
我只能分析给定的数据,所以在这种情况下只能分析来自
的链接政府文件
被提取为
ìëéî ìù "íééç éøåùéë" øôñá ,äéãôåìòôäá íéáø úåðåéòø ãåò àåöîì ïúéð
.ãåòå úéëåðéçä äééæëøîá ,567 'îò ,ïîöìæ éìéðå ì÷ðøô äéæø ,ïîæåø
在这种情况下,乱码 输出的原因很简单:PDF 声称乱码 确实是那里的文本!
因此,问题不在于文本提取器,无论是 iText PdfTextExtractor
、Adobe Reader 复制粘贴还是其他任何一个。相反,问题在于其内容的文档
更详细
本段使用的字体 TT1 有一个 ToUnicode 条目,映射如下:
28 beginbfchar
<0003> <0020>
<0005> <0022>
<000a> <0027>
<000f> <002C>
<0011> <002E>
<001d> <003A>
<0069> <00E1>
<006a> <00E0>
<006b> <00E2>
<006c> <00E4>
<006d> <00E3>
<006e> <00E5>
<006f> <00E7>
<0070> <00E9>
<0071> <00E8>
<0074> <00ED>
<0075> <00EC>
<0078> <00F1>
<0079> <00F3>
<007a> <00F2>
<007b> <00F4>
<007c> <00F6>
<007e> <00FA>
<007f> <00F9>
<0096> <00E6>
<0097> <00F8>
<00ab> <00F7>
<00d5> <00F0>
endbfchar
3 beginbfrange
<0018> <001a> <0035>
<0072> <0073> <00EA>
<0076> <0077> <00EE>
endbfrange
即所有代码都映射到 U+0020 和 U+00F9 之间的 Unicode 值,这是一个 Unicode 范围,其中显然没有在屏幕截图中看到的希伯来语字符。更确切地说:除了 space、一些标点符号和数字(已正确提取)之外,这些值在 U+00E0 和 U+00F9 之间的范围内,这是带有重音符号的拉丁字母及其同类所在的区域。
您提到在某些情况下您可以通过应用
来检索希伯来语文本
new String(text.getBytes(Charset.forName("ISO-8859-1")), Charset.forName("windows-1255"))
所以 PDF 创建工具可能已将 Windows-1255 代码页的映射放入 ToUnicode 映射中。这显然是错误的,ToUnicode 映射必须包含到 Unicode 的映射。
综上所述,即使 ToUnicode 映射是正确的,您仍然需要与反向希伯来语输出作斗争。这确实是 iText 5.x 文本提取的一个限制,它没有对 RTL 语言的特殊支持。因此,您必须自己更改结果字符串中字符的顺序。
在 this answer 中,您将找到此类重新排序方法的示例。它适用于阿拉伯语脚本并且使用 C#,但它清楚地显示了如何进行。
首先,最合适的希伯来语字节字符集是 "ISO-8859-8"(比 windows-1255 更好)。尝试玩这个。另外,我会尝试使用字符集 UTF-8 提取字符串。
还有一个很棒的诊断工具可以帮助我诊断和解决与希伯来语和阿拉伯语相关的无数棘手的编码问题
有一个开源 java 库 MgntUtils 有一个实用程序将字符串转换为 unicode 序列,反之亦然:
result = "שלום את";
result = StringUnicodeEncoderDecoder.encodeStringToUnicodeSequence(result);
System.out.println(result);
result = StringUnicodeEncoderDecoder.decodeUnicodeSequenceToString(result);
System.out.println(result);
这段代码的输出是:
\u05e9\u05dc\u05d5\u05dd\u0020\u05d0\u05ea
שלום את
这是 javadoc 的 class StringUnicodeEncoderDecoder As you can see the Unicode symbols for Hebrew is U+05** where the first Hebrew letter (Alef -א) is U+05d0 and the last Hebrew letter (Tav - ת) is U+05ea.
The library can be found at Maven Central or at Github 它作为 maven 工件和来源以及 javadoc
所以我会做什么首先是获取您的原始字符串并将其转换为 unicode 序列,然后查看您实际到达那里的内容。如果数据不正确,则尝试提取字节并使用 UTF-8 构建字符串。无论如何,我强烈推荐使用这个实用程序,因为它帮助了我很多次。
使用 ICU 完成了工作:
Bidi bidi = new Bidi();
bidi.setPara(input, Bidi.RTL, null);
String output = bidi.writeReordered(Bidi.DO_MIRRORING);
我正在使用 iText5 解析主要用希伯来语编写的 pdf。
要提取文本,我使用 PdfTextExtractor.getTextFromPage
。我没有找到更改库中编码的方法,文本显示为乱码。
我试过这样修复编码:
new String(pdfPage.getBytes(Charset1), Charset2)
.
我使用 Charset.availableCharsets()
遍历了所有可能的字符集,其中很少有人给了我希伯来语而不是乱码但相反。
现在我以为我可以逐行反转文本,但是希伯来语是从右到左,数字和英语是从左到右。因此,如果我反转行,它会修复希伯来语但会破坏 numbers/English.
示例:
PdfTextExtractor.getTextFromPage
returns 87.55 úåáééçúä ééåëéð ë"äñ
new String(text.getBytes(Charset.forName("ISO-8859-1")), Charset.forName("windows-1255"))
returns 87.55 תובייחתה ייוכינ כ"הס
如果我反转这个然后我得到 סה"כ ניכויי התחייבות 55.78
数字应该是 87.55
而不是 55.78
我找到的唯一解决方案是将其拆分为希伯来语和其余部分 (English/numbers),仅反转希伯来语部分,然后将其合并回去。
没有更简单的解决方案吗?我觉得我在 encoding/RTL
中遗漏了一些东西I cant share the document I'm working on because it contains PII. But after searching Goole for pdf with gibberish, I found this document - the last paragraph of the document has exactly the same problem I have in my documents.
我只能分析给定的数据,所以在这种情况下只能分析来自
的链接政府文件被提取为
ìëéî ìù "íééç éøåùéë" øôñá ,äéãôåìòôäá íéáø úåðåéòø ãåò àåöîì ïúéð
.ãåòå úéëåðéçä äééæëøîá ,567 'îò ,ïîöìæ éìéðå ì÷ðøô äéæø ,ïîæåø
在这种情况下,乱码 输出的原因很简单:PDF 声称乱码 确实是那里的文本!
因此,问题不在于文本提取器,无论是 iText PdfTextExtractor
、Adobe Reader 复制粘贴还是其他任何一个。相反,问题在于其内容的文档
更详细
本段使用的字体 TT1 有一个 ToUnicode 条目,映射如下:
28 beginbfchar
<0003> <0020>
<0005> <0022>
<000a> <0027>
<000f> <002C>
<0011> <002E>
<001d> <003A>
<0069> <00E1>
<006a> <00E0>
<006b> <00E2>
<006c> <00E4>
<006d> <00E3>
<006e> <00E5>
<006f> <00E7>
<0070> <00E9>
<0071> <00E8>
<0074> <00ED>
<0075> <00EC>
<0078> <00F1>
<0079> <00F3>
<007a> <00F2>
<007b> <00F4>
<007c> <00F6>
<007e> <00FA>
<007f> <00F9>
<0096> <00E6>
<0097> <00F8>
<00ab> <00F7>
<00d5> <00F0>
endbfchar
3 beginbfrange
<0018> <001a> <0035>
<0072> <0073> <00EA>
<0076> <0077> <00EE>
endbfrange
即所有代码都映射到 U+0020 和 U+00F9 之间的 Unicode 值,这是一个 Unicode 范围,其中显然没有在屏幕截图中看到的希伯来语字符。更确切地说:除了 space、一些标点符号和数字(已正确提取)之外,这些值在 U+00E0 和 U+00F9 之间的范围内,这是带有重音符号的拉丁字母及其同类所在的区域。
您提到在某些情况下您可以通过应用
来检索希伯来语文本new String(text.getBytes(Charset.forName("ISO-8859-1")), Charset.forName("windows-1255"))
所以 PDF 创建工具可能已将 Windows-1255 代码页的映射放入 ToUnicode 映射中。这显然是错误的,ToUnicode 映射必须包含到 Unicode 的映射。
综上所述,即使 ToUnicode 映射是正确的,您仍然需要与反向希伯来语输出作斗争。这确实是 iText 5.x 文本提取的一个限制,它没有对 RTL 语言的特殊支持。因此,您必须自己更改结果字符串中字符的顺序。
在 this answer 中,您将找到此类重新排序方法的示例。它适用于阿拉伯语脚本并且使用 C#,但它清楚地显示了如何进行。
首先,最合适的希伯来语字节字符集是 "ISO-8859-8"(比 windows-1255 更好)。尝试玩这个。另外,我会尝试使用字符集 UTF-8 提取字符串。
还有一个很棒的诊断工具可以帮助我诊断和解决与希伯来语和阿拉伯语相关的无数棘手的编码问题
有一个开源 java 库 MgntUtils 有一个实用程序将字符串转换为 unicode 序列,反之亦然: result = "שלום את";
result = StringUnicodeEncoderDecoder.encodeStringToUnicodeSequence(result);
System.out.println(result);
result = StringUnicodeEncoderDecoder.decodeUnicodeSequenceToString(result);
System.out.println(result);
这段代码的输出是:
\u05e9\u05dc\u05d5\u05dd\u0020\u05d0\u05ea
שלום את
这是 javadoc 的 class StringUnicodeEncoderDecoder As you can see the Unicode symbols for Hebrew is U+05** where the first Hebrew letter (Alef -א) is U+05d0 and the last Hebrew letter (Tav - ת) is U+05ea.
The library can be found at Maven Central or at Github 它作为 maven 工件和来源以及 javadoc
所以我会做什么首先是获取您的原始字符串并将其转换为 unicode 序列,然后查看您实际到达那里的内容。如果数据不正确,则尝试提取字节并使用 UTF-8 构建字符串。无论如何,我强烈推荐使用这个实用程序,因为它帮助了我很多次。使用 ICU 完成了工作:
Bidi bidi = new Bidi();
bidi.setPara(input, Bidi.RTL, null);
String output = bidi.writeReordered(Bidi.DO_MIRRORING);