見出し画像

2つのwordファイルの文字を比較する Python


今回やりたいこと

英語学習において、音声認識によって取得した文章をwordファイルに保存したものと、同じ音声を自分が聞いて、その文章をwordファイルに保存したものがある。それぞれのファイル内の英語の文章が同じかどうかを判定したい。

ChatGPTの活用

最初から全て自分で考えるのもいいが、時短のためにChatGPTを活用した。
無料版で次のように入力した。

「pythonで2つのwordファイルからそれぞれ文書を読み取り、文書の各単語が一致している箇所には黒文字、異なる場合には赤文字で新しいwordファイルに保存する。」

この時の出力結果は、

from docx import Document
from docx.shared import RGBColor

def read_words_from_docx(file_path):
    """Wordファイルを読み込み、単語のリストを返す。"""
    doc = Document(file_path)
    words = []
    for para in doc.paragraphs:
        words.extend(para.text.split())  # 各段落のテキストを取得し、単語に分割
    return words

def create_comparison_doc(words1, words2, output_path):
    """2つの単語リストを比較し、結果を新しいWordファイルに保存する。"""
    doc = Document()
    min_len = min(len(words1), len(words2))  # 比較のため、短い方のリストに合わせる

    for i in range(min_len):
        if words1[i] == words2[i]:
            # 一致する単語は黒文字で追加
            run = doc.add_paragraph().add_run(words1[i] + " ")
            run.font.color.rgb = RGBColor(0, 0, 0)
        else:
            # 異なる単語は赤文字で追加
            run1 = doc.add_paragraph().add_run(words1[i] + " ")
            run1.font.color.rgb = RGBColor(255, 0, 0)

            run2 = doc.add_paragraph().add_run(words2[i] + " ")
            run2.font.color.rgb = RGBColor(255, 0, 0)

    # どちらかが長い場合、その残りの単語も追加
    if len(words1) > min_len:
        for word in words1[min_len:]:
            run = doc.add_paragraph().add_run(word + " ")
            run.font.color.rgb = RGBColor(255, 0, 0)
    elif len(words2) > min_len:
        for word in words2[min_len:]:
            run = doc.add_paragraph().add_run(word + " ")
            run.font.color.rgb = RGBColor(255, 0, 0)

    # ファイルを保存
    doc.save(output_path)

# ファイルのパスを指定
file1_path = "file1.docx"
file2_path = "file2.docx"
output_path = "comparison.docx"

# 各ファイルから単語を読み取り
words1 = read_words_from_docx(file1_path)
words2 = read_words_from_docx(file2_path)

# 比較して新しいWordファイルに保存
create_comparison_doc(words1, words2, output_path)

print("比較結果が 'comparison.docx' に保存されました。")

となる。しかし、この場合の出力は単語リストのようになって出てくるので、次のように修正を加える。

「出力は単語リストではなく、文章として出力して」

そうすると、

from docx import Document
from docx.shared import RGBColor

def read_words_from_docx(file_path):
    """Wordファイルを読み込み、段落ごとに単語リストを作成する。"""
    doc = Document(file_path)
    text = " ".join([para.text for para in doc.paragraphs])
    return text.split()  # 全テキストを単語ごとに分割

def create_comparison_doc(words1, words2, output_path):
    """2つの単語リストを比較し、文章として結果をWordに保存する。"""
    doc = Document()
    paragraph = doc.add_paragraph()  # 1つの段落にまとめて書き込む

    min_len = min(len(words1), len(words2))  # 短い方のリストに合わせて比較

    for i in range(min_len):
        if words1[i] == words2[i]:
            # 一致する単語は黒文字で追加
            run = paragraph.add_run(words1[i] + " ")
            run.font.color.rgb = RGBColor(0, 0, 0)
        else:
            # 異なる単語は赤文字で追加
            run = paragraph.add_run(words1[i] + " ")
            run.font.color.rgb = RGBColor(255, 0, 0)

    # 残りの単語を追加(どちらかが長い場合)
    if len(words1) > min_len:
        for word in words1[min_len:]:
            run = paragraph.add_run(word + " ")
            run.font.color.rgb = RGBColor(255, 0, 0)
    elif len(words2) > min_len:
        for word in words2[min_len:]:
            run = paragraph.add_run(word + " ")
            run.font.color.rgb = RGBColor(255, 0, 0)

    # ファイルを保存
    doc.save(output_path)

# ファイルのパスを指定
file1_path = "file1.docx"
file2_path = "file2.docx"
output_path = "comparison.docx"

# 各ファイルから単語を読み取り
words1 = read_words_from_docx(file1_path)
words2 = read_words_from_docx(file2_path)

# 比較して新しいWordファイルに保存
create_comparison_doc(words1, words2, output_path)

print("比較結果が 'comparison.docx' に保存されました。")

paragraph = doc.add_paragraph() # 1つの段落にまとめて書き込む
が追加され、文章として書き込まれるようになった。

実際に、wordファイルを準備して実行させると、異なる部分は赤文字となっていることが確認できた。

また、日本語版の場合は、英語のように単語の間に空白がないため、Janomeライブラリというものを使用するらしい。(以下のコードは動作未確認なので、参考程度に)

from docx import Document
from docx.shared import RGBColor
from janome.tokenizer import Tokenizer

def read_words_from_docx(file_path):
    """Wordファイルからテキストを取得し、日本語の単語に分割する。"""
    doc = Document(file_path)
    text = " ".join([para.text for para in doc.paragraphs])  # 段落を結合
    tokenizer = Tokenizer()
    words = [token.surface for token in tokenizer.tokenize(text)]  # 形態素解析
    return words

def create_comparison_doc(words1, words2, output_path):
    """2つの単語リストを比較し、文章として結果をWordに保存する。"""
    doc = Document()
    paragraph = doc.add_paragraph()  # 1つの段落にまとめて書き込む

    min_len = min(len(words1), len(words2))  # 短い方のリストに合わせて比較

    for i in range(min_len):
        if words1[i] == words2[i]:
            # 一致する単語は黒文字で追加
            run = paragraph.add_run(words1[i])
            run.font.color.rgb = RGBColor(0, 0, 0)
        else:
            # 異なる単語は赤文字で追加
            run = paragraph.add_run(words1[i])
            run.font.color.rgb = RGBColor(255, 0, 0)
        paragraph.add_run(" ")  # 単語の間にスペースを追加

    # 残りの単語を追加(どちらかが長い場合)
    if len(words1) > min_len:
        for word in words1[min_len:]:
            run = paragraph.add_run(word + " ")
            run.font.color.rgb = RGBColor(255, 0, 0)
    elif len(words2) > min_len:
        for word in words2[min_len:]:
            run = paragraph.add_run(word + " ")
            run.font.color.rgb = RGBColor(255, 0, 0)

    # ファイルを保存
    doc.save(output_path)

# ファイルのパスを指定
file1_path = "file1.docx"
file2_path = "file2.docx"
output_path = "comparison.docx"

# 各ファイルから単語を読み取り
words1 = read_words_from_docx(file1_path)
words2 = read_words_from_docx(file2_path)

# 比較して新しいWordファイルに保存
create_comparison_doc(words1, words2, output_path)

print("比較結果が 'comparison.docx' に保存されました。")

この内容は他のところでも応用できると思うので、参考にしてみてください。

サイト

https://sites.google.com/view/elemagscience/%E3%83%9B%E3%83%BC%E3%83%A0


いいなと思ったら応援しよう!