代码之家  ›  专栏  ›  技术社区  ›  Boaz

在使用iText解析PDF文档后反转希伯来语或数字

  •  1
  • Boaz  · 技术社区  · 6 年前

    我正在使用iText5解析一个主要用希伯来语编写的pdf文件。
    PdfTextExtractor.getTextFromPage . 我没有找到方法来改变库中的编码,文本显得乱七八糟。


    new String(pdfPage.getBytes(Charset1), Charset2) .
    我用了所有可能的字符集 Charset.availableCharsets()

    现在我想我可以一行一行地倒转文本,但是希伯来语从右到左,数字和英语从左到右。所以如果我把这条线倒过来,它会修正希伯来语,但会破坏数字/英语。

    PdfTextExtractor.getTextFromPage 回报 87.55 úåáééçúä ééåëéð ë"äñ

    new String(text.getBytes(Charset.forName("ISO-8859-1")), Charset.forName("windows-1255")) 回报 87.55 תובייחתה ייוכינ כ"הס

    如果我把这个倒过来 סה"כ ניכויי התחייבות 55.78

    号码应该是 87.55 而不是 55.78

    难道没有更简单的解决办法吗?我觉得编码/RTL丢失了一些东西

    3 回复  |  直到 6 年前
        1
  •  1
  •   mkl    6 年前

    我无法共享我正在处理的文档,因为它包含PII。但在google上搜索了一些乱七八糟的pdf文件后,我发现了这个 document -文件的最后一段与我在文件中遇到的问题完全相同。

    screen shot

    提取为

    ìëéî ìù "íééç éøåùéë" øôñá ,äéãôåìòôäá íéáø úåðåéòø ãåò àåöîì ïúéð 􀂛
    .ãåòå úéëåðéçä äééæëøîá ,567 'îò ,ïîöìæ éìéðå ì÷ðøô äéæø ,ïîæåø
    

    在这种情况下 输出很简单:PDF声称 真的有文字吗!

    因此,问题不是文本提取器,而是iText PdfTextExtractor

    更详细

    TT1型 用于此段落的 图尼科德 具有以下映射的条目:

    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 
    

    一、 e.所有代码都映射到U+0020和U+00F9之间的Unicode值,这是一个Unicode范围,在这个范围内,屏幕截图中看到的希伯来语字符显然不在其中。更确切地说:除了空格、一些标点符号和数字(它们被正确提取)之外,这些值在U+00E0和U+00F9之间,这是一个带有重音符号的拉丁字母及其类似字母所在的区域。

    new String(text.getBytes(Charset.forName("ISO-8859-1")), Charset.forName("windows-1255"))
    

    因此,PDF创建工具可能已经将到Windows-1255代码页的映射放到 图尼科德 地图。显然是错误的 映射必须包含到Unicode的映射。


    图尼科德 映射是正确的,您仍然需要使用反向希伯来语输出。这确实是iText 5.x文本提取的一个限制,它对RTL语言没有特殊的支持。因此,您必须自己更改结果字符串中字符的顺序。

    this answer

        2
  •  1
  •   Michael Gantman    6 年前

    首先,最合适的希伯来语字节字符集是“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 StringUnicodeEncoderDecoder 如您所见,希伯来语的Unicode符号是U+05**,其中第一个希伯来语字母(Alef-×)是U+05d0,最后一个希伯来语字母(Tav-×)是U+05ea。

    Maven Central 或者在 Github

    所以我首先要做的是得到原始字符串并将其转换为unicode序列,然后看看实际得到了什么。如果数据不正确,则尝试提取字节并用UTF-8构建字符串。无论如何,我强烈建议使用这个实用程序,因为它帮助了我很多次。
        3
  •  0
  •   Boaz    6 年前

    使用 ICU

    Bidi bidi = new Bidi();
    bidi.setPara(input, Bidi.RTL, null);
    String output = bidi.writeReordered(Bidi.DO_MIRRORING);