replace.py 技術ドキュメント


プログラムの動作

replace.py は、指定されたテキストファイルの内容を、設定ファイルで定義された正規表現パターンに基づいて置換するプログラムです。主に、大量のテキストデータにおける表記ゆれや特定のフレーズの一括修正、あるいは書式変換などの用途に利用できます。

主な機能:

  • 入力ファイルの文字コード自動検出: chardet ライブラリを使用して、入力ファイルの文字コードを自動的に判定し、適切に読み込みます。

  • 柔軟な置換ルール定義: INI 形式の設定ファイル (replace.ini など) から、正規表現パターンとその置換文字列のペアを読み込みます。

  • ユーザー定義ルールの優先: デフォルトの置換ルールファイルとユーザー定義の置換ルールファイルの両方を指定でき、ユーザー定義ルールがデフォルトルールよりも優先されます。重複するキーはユーザー定義ルールが適用され、デフォルトルールからは除外されます。

  • 正規表現による強力な置換: Pythonの re モジュールを利用し、大文字小文字を区別しない、複数行対応などのフラグを設定した正規表現置換を実行します。

  • 自動的な出力ファイル名生成: 出力ファイルが指定されない場合、入力ファイル名に -converted を付加した名前で自動生成します。

原理

このプログラムは以下の原理に基づいて動作します。

  1. ライブラリの事前チェック: 必要な非標準ライブラリ(chardet)がインストールされているかを確認し、不足している場合はエラーメッセージを表示して終了します。

  2. 文字コード検出: detect_encoding 関数は、入力ファイルをバイナリモード ('rb') で読み込み、chardet.detect() 関数を用いてファイルの文字コードを推定します。これにより、多種多様なエンコーディングのファイルに対応できます。

  3. 置換辞書のロード: load_replace_dict 関数は、指定されたINIファイルを解析し、キー=値 の形式の行を置換ルールとして辞書に格納します。

    • 行頭が # の行はコメントとして無視されます。

    • キーは正規表現パターン、値は置換文字列です。

    • キーがシングルクォートまたはダブルクォートで囲まれている場合 ('key'=value または "key"=value)、クォートを削除してキーとして使用します。

    • この解析には、3重引用符 で囲まれた正規表現リテラル r"^(['\"].+?['\"]|[^=]+?)=(.*)$" が使用され、キーと値を正確に抽出します。

  4. 置換ルールの適用順序と優先順位:

    • ユーザー定義の置換ファイル (replace_file2) とデフォルトの置換ファイル (replace_file) の両方が読み込まれます。

    • dict2 (ユーザー定義) に存在するキーは dict1 (デフォルト) から除外されます。これにより、ユーザー定義のルールがデフォルトのルールよりも優先されます。

    • 置換はまず dict2 のルール群がテキスト全体に適用され、次に dict1_filtered のルール群が、dict2 適用後のテキストに適用されます。各ルールは辞書からリストに変換された順序で一つずつ適用されます。

  5. 正規表現置換: apply_replacements 関数は、与えられたテキストに対し、正規表現パターンと置換文字列のペアを順次適用します。

    • re.sub(pattern, replacement, text, flags=re.IGNORECASE | re.MULTILINE) を使用して置換を実行します。

    • re.IGNORECASE フラグにより、大文字小文字を区別せずにパターンマッチングを行います。

    • re.MULTILINE フラグにより、正規表現の ^$ が行頭と行末にマッチするようになります。

  6. 出力: 全ての置換処理が完了した後、最終的なテキストは指定された出力ファイルにUTF-8エンコーディングで書き込まれます。

このプログラムでは、特定の数式や物理式は直接使用されていません。アルゴリズムは主にテキスト処理と正規表現に基づいています。

必要な非標準ライブラリとインストール方法

このプログラムは、文字コードの自動検出のために以下の非標準ライブラリを必要とします。

  • chardet: ファイルのエンコーディングを検出するために使用されます。

インストール方法:

コマンドプロンプトやターミナルで以下の pip コマンドを実行してインストールできます。

pip install chardet

必要な入力ファイル

1. 入力テキストファイル

置換処理の対象となるテキストファイルです。

  • パス: コマンドライン引数 --input_file または -i で指定します。指定しない場合、デフォルトで input.md が使用されます。

  • 形式: 任意のテキスト形式(例: .md, .txt, .html など)。プログラムが自動で文字コードを検出しようと試みます。

2. 置換ルールファイル (INI形式)

置換パターンと置換文字列を定義するファイルです。

  • パス:

    • デフォルトの置換ルールファイル: コマンドライン引数 --replace_file または -r で指定します。指定しない場合、デフォルトで replace.ini が使用されます。

    • ユーザー定義の置換ルールファイル: コマンドライン引数 --replace_file2 または -s で指定します。指定しない場合、デフォルトで空文字列が使用され、ファイルは読み込まれません。

  • 形式: INIファイル形式に似たシンプルなキーバリューペアのリストです。

    • 各行は 正規表現パターン=置換文字列 の形式で記述します。

    • 行頭が # の行はコメントとして無視されます。

    • 正規表現パターン(キー)は、シングルクォート ' またはダブルクォート " で囲むことができます。この場合、クォートはキーとして扱われず、パターンの一部と見なされます。

    • 置換文字列(値)は、前後の空白を含めてそのまま扱われます。

replace.ini の例:

# This is a comment line.
"古いテキスト"=新しいテキスト
パターンA=置換文字列A
'Pattern B'=Replacement B With Spaces
[0-9]+=[NUMBER]

生成される出力ファイル

置換処理が適用された結果のテキストが保存されるファイルです。

  • ファイル名: コマンドライン引数 --output_file または -o で指定します。

    • 指定がない場合、入力ファイル名に -converted を付加した名前が自動で生成されます。

      • 例: input.md -> input-converted.md

      • 例: document.txt -> document-converted.txt

  • 内容: 入力テキストに全ての置換ルールが適用された後の最終的なテキスト。

  • 文字コード: UTF-8 で書き出されます。

コマンドラインでの使用例 (Usage)

replace.py は以下の形式でコマンドラインから実行します。

python replace.py [-i INPUT_FILE] [-o OUTPUT_FILE] [-r REPLACE_FILE] [-s REPLACE_FILE2]

引数:

  • -i INPUT_FILE, --input_file INPUT_FILE: 入力テキストファイルのパス。デフォルトは input.md

  • -o OUTPUT_FILE, --output_file OUTPUT_FILE: 出力ファイルのパス。指定がない場合、入力ファイル名から自動生成されます。

  • -r REPLACE_FILE, --replace_file REPLACE_FILE: デフォルトの置換ルールファイル (.ini) のパス。デフォルトは replace.ini

  • -s REPLACE_FILE2, --replace_file2 REPLACE_FILE2: ユーザー定義の置換ルールファイル (.ini) のパス。このファイルに定義されたルールは、デフォルトファイルと重複する場合に優先されます。デフォルトは空文字列 (指定なし)。

コマンドラインでの具体的な使用例

以下のファイルが存在すると仮定します。

input.txt の内容:

Hello World! This is a test.
Test for REPLACE.

replace.ini の内容 (デフォルトルール):

World=Python
Test=Example

user_replace.ini の内容 (ユーザー定義ルール、Testreplace.ini と重複):

Hello=Hi
Test=UserTest

実行コマンド

input.txt を読み込み、replace.iniuser_replace.ini のルールを適用して output.txt に出力します。

python replace.py -i input.txt -o output.txt -r replace.ini -s user_replace.ini

実行結果の説明

上記のコマンドを実行すると、以下のようなプロセスを経て output.txt が生成されます。

  1. 入力ファイル読み込み: input.txt が読み込まれます。

  2. 置換辞書ロード:

    • user_replace.ini から { 'Hello': 'Hi', 'Test': 'UserTest' } が読み込まれ、ユーザー定義ルール (dict2) となります。

    • replace.ini から { 'World': 'Python', 'Test': 'Example' } が読み込まれ、デフォルトルール (dict1) となります。

  3. ルール優先順位の適用:

    • dict2'Test' が存在するため、dict1 から 'Test' ルールが除外されます。

    • 結果として、適用されるデフォルトルールは { 'World': 'Python' } (dict1_filtered) となります。

  4. 置換処理:

    • まず、ユーザー定義ルール (dict2) が適用されます。

      • HelloHi

      • TestUserTest

      • この段階でテキストは Hi World! This is a UserTest.\nUserTest for REPLACE. となります。

    • 次に、フィルターされたデフォルトルール (dict1_filtered) が適用されます。

      • WorldPython

      • この段階でテキストは Hi Python! This is a UserTest.\nUserTest for REPLACE. となります。

  5. 出力: 最終的なテキストが output.txt に書き出されます。

output.txt の内容:

Hi Python! This is a UserTest.
UserTest for REPLACE.