PDFから文字抽出抽出する文字列に全角スペースが含まれていた場合、半角のスペースに置き換えます。
PDFから抽出する文字列の中に和字間隔が混ざっていたら、スペース(Unicode 0020)に置き換えることができます。和字間隔はIDEOGRAPHIC SPACEと呼ばれ、日本語の環境では一般に全角スペースとして使われている文字のことです。以降、「和字間隔」のことを「全角スペース」と表記します。
PtlParamExtractText.setUnicodeToSpace()を使用します。
AHEXTRACTTEXT_UNI_IDEOGRAPHIC_SPACEを指定することで、抽出した文字列に含まれた全角スペースを半角のスペースに置き換えます。置き換える特殊文字の指定はint型フラグで行います。
サンプルプログラムでは、入力PDFの指定したページ全体から文字列を抜き出す際に、指定可能な特殊文字について削除する・しないを切り替えた上で抽出します。
列挙型定数 | 特殊文字の種別 -> ユニコード |
---|---|
AHEXTRACTTEXT_UNI_C0_CONTROLS | C0制御文字 -> U+0000-U+001F |
AHEXTRACTTEXT_UNI_SPACE | 単体のスペース -> U+0020 |
AHEXTRACTTEXT_UNI_NO_BREAK_SPACE | ノーブレークスペース-> U+00A0 |
AHEXTRACTTEXT_UNI_SOFT_HYPHEN | ソフトハイフン-> U+00AD |
AHEXTRACTTEXT_UNI_SPACES | UnicodeのU+2000~U+200Bの 主に“Spaces” カテゴリに含まれる特殊スペース -> U+2000-U+200B |
AHEXTRACTTEXT_UNI_IDEOGRAPHIC_SPACE | 全角スペース-> U+3000 |
AHEXTRACTTEXT_UNI_VARIATION_SELECTOR | 異体字セレクタ-> U+FE00-U+FE0F |
AHEXTRACTTEXT_UNI_REPLACEMENT_CHARACTER | 置き換え文字 -> U+FFFD |
AHEXTRACTTEXT_UNI_ALL | 上記全てを対象とする(今後のバージョンアップでフラグが増えたらそれも含む)。 |
package cookbook; import java.io.BufferedWriter; import java.io.PrintWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.charset.StandardCharsets; import jp.co.antenna.ptl.*; public class ExtTextWithRplcIdeographicSpaceToSpace { // そのクラスのusageを表示する関数 private static void printUsage() { System.out.println("usage: java ExtractTextWithReplacingSpecialCharToSpace in-pdf-file out-text-file" + " page-to-extract rplc-ideographic-space"); System.out.println("--以下の文字に対して、[0:スペースに置き換えない 1:置き換える]を選択--"); System.out.println("rplc-ideographic-space : 全角スペース"); } /** * @param args the command line arguments */ public static void main(String[] args) { if (args.length < 4) { printUsage(); // usageメッセージの表示 return; } // コマンドライン引数の読み取り・判定 // 出力PDFの名前はあとで渡すためにString型で保存する。 String outputTextURI = args[1]; int pageToExtract = Integer.parseInt(args[2]); boolean rplcIdeographicSpace = false; int unicodeCharFlag = 0; //各種削除フラグの読み取り判定 //rplc-ideographic-space try { rplcIdeographicSpace = readBoolArgs(args[3], "rplc-ideographic-spaceは" + "0か1で指定してください。"); } catch (IllegalArgumentException ex) { System.out.println(ex.getMessage()); printUsage(); // usageメッセージの表示 return; } //各フラグの論理和をunicodeCharFlagに設定 if(rplcIdeographicSpace) { unicodeCharFlag = unicodeCharFlag | PtlParamExtractText.AHEXTRACTTEXT_UNI_IDEOGRAPHIC_SPACE; } try(PtlParamInput inputFile = new PtlParamInput(args[0]); PtlPDFDocument doc = new PtlPDFDocument()) { // PDFファイルをロード doc.load(inputFile); try(PtlPages pages = doc.getPages()) {//ページコンテナの取得 // ページコンテナが空かどうか if(pages.isEmpty()) { System.out.println("ERROR : ページコンテナが空"); throw new Error("ERROR : ページコンテナが空"); } //ページ数を取得 int wholePageNum = doc.getPageCount(); //pageToExtractが0ならすべてのページを処理する if(pageToExtract == 0) { StringBuilder wholeTextFromPdf = new StringBuilder(); // ページの取得(パラメータindexは0が先頭のため1を引く) for(int i = 0; i < wholePageNum; i++) { try(PtlPage page = pages.get(i); PtlContent content = page.getContent()) { // ページコンテントの取得 System.out.println((i+1) + "ページ目のテキストを抽出します。"); wholeTextFromPdf.append(extractTextSetReplaceUnicodeFlag(unicodeCharFlag, content)); } } outputTextFile(outputTextURI, wholeTextFromPdf.toString()); }else { if(wholePageNum < pageToExtract) { //pageToExtractのエラー処理 System.out.println("ERROR: page-to-extractはPDFの総ページ数より"+ "小さい値を指定してください。"); System.out.println("総ページ数:" + wholePageNum); printUsage(); throw new Error("ERROR: page-to-extractはPDFの総ページ数より"+ "小さい値を指定してください。"); } try(PtlPage page = pages.get(pageToExtract - 1); //指定したページを取得する PtlContent content = page.getContent()) { System.out.println(pageToExtract + "ページ目のテキストを抽出します。"); outputTextFile(outputTextURI, extractTextSetReplaceUnicodeFlag(unicodeCharFlag, content)); } } } } ...【GetPDFVersion.javaと同じ処理のため省略 ・エラーメッセージ処理と出力】... } private static String extractTextSetReplaceUnicodeFlag(int unicodeCharFlag, PtlContent content) throws IOException, PtlException, Exception, Error { try(PtlParamExtractText paramExtractText = new PtlParamExtractText()) { // 文字抽出のパラメータクラス。 //setUnicodeToRemoveをパラメータに設定 paramExtractText.setUnicodeToSpace(unicodeCharFlag); // 文字列抽出 String textFromPdf = content.extractText(paramExtractText); System.out.println(textFromPdf); // 抽出した文字列を返す return textFromPdf; } } /** * テキストファイルを出力するための関数。 * 出力エンコードはUTF-8を指定する。 * 特に外部からの呼び出しを想定しないためprivateとする。 * * @param outputTextURI 出力ファイルのURI。 * @param TextFromPdf 出力したいString型変数 */ private static void outputTextFile(String outputTextURI, String TextFromPdf){ ...【ExtractTextSetRect.javaと同じ処理のため省略 ・outputTextURIのパスにTextFromPDFの内容をUTF-8エンコーディングで出力する処理】... } /** * 0または1を入力されたargsにより、trueまたはfalseを返すメソッド。 * * @param args 与えられるコマンドライン引数。0または1でtrueまたはfalseを指定する。 * @param errorMessage argsが0か1でなかった場合に出力されるエラーメッセージを指定する。 * @return argsの数値を読み取った結果を戻す * @throws java.lang.IllegalArgumentException argsが0か1でなかった場合に発生。 */ public static boolean readBoolArgs(String args, String errorMessage) throws IllegalArgumentException { ...【FixUpPDFASetSaveOption.javaと同じ処理のため省略 ・0または1を読み取り、boolean型のfalseまたはtrueを返す関数】... } }
ExtTextWithRplcIdeographicSpaceToSpace.java
C:\samples>java cookbook.ExtTextWithRplcIdeographicSpaceToSpace usage: java ExtractTextWithReplacingSpecialCharToSpace in-pdf-file out-text-file page-to-extract rplc-ideographic-space --以下の文字に対して、[0:スペースに置き換えない 1:置き換える]を選択-- rplc-ideographic-space : 全角スペース C:\samples>java cookbook.ExtTextWithRplcIdeographicSpaceToSpace Special_letter_sample_IdeographicSpace.pdf Output_ExtTextWithRplcIdeographicSpaceToSpace.txt 0 1 1ページ目のテキストを抽出します。 特殊文字一覧IDEOGRAPHIC SPACEIDEOGRAPHIC SPACE(U3000) ishere" ""The quick brown fox jumps over the lazy dog" Output text URI :Output_ExtTextWithRplcIdeographicSpaceToSpace.txt -- 完了 --
この操作例では例文の空白がすべてIDEOGRAPHIC SPACEのPDFが使われています。
下図はIDEOGRAPHIC SPACEを半角スペースに置き換えた場合とそのままの状態の比較です。