
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を半角スペースに置き換えた場合とそのままの状態の比較です。

