Pythonにおける文字列処理と正規表現の応用実践

概要

本記事では、Pythonを使用した文字列操作の基礎から、正規表現(Regular Expression)を用いた高度なパターンマッチングまで、実践的な実装例を通じて解説します。具体的には、文字列の解析、文字分類、変換処理、簡易的な暗号化アルゴリズム、およびテキストマイニングにおけるデータ抽出手法について取り上げます。

1. 文字列要素の分析(最大・最小の抽出)

空白文字で区切られた文字列を入力とし、その中から最長および最短の部分文字列、さらに文字列全体に含まれる最大および最小の文字をASCIIコードに基づいて特定する機能を実装します。


def analyze_text_components(target_str):
    # 空白で分割して部分文字列のリストを作成
    substrings = target_str.split()
    
    # 比較のため空白を除去した文字列を作成
    cleaned_str = target_str.replace(' ', '')
    
    if not substrings:
        return None, None, None, None

    # 最長・最短の部分文字列を取得
    longest_sub = max(substrings, key=len)
    shortest_sub = min(substrings, key=len)
    
    # 文字コード順の最大・最小文字を取得
    max_char = max(cleaned_str) if cleaned_str else ''
    min_char = min(cleaned_str) if cleaned_str else ''
    
    return longest_sub, shortest_sub, max_char, min_char

if __name__ == "__main__":
    user_input = input("文字列を入力してください: ")
    l_sub, s_sub, m_char, mn_char = analyze_text_components(user_input)
    print(f"最長部分文字列: {l_sub}")
    print(f"最短部分文字列: {s_sub}")
    print(f"最大文字: {m_char}")
    print(f"最小文字: {mn_char}")

2. 文字種別の判定

単一の文字入力を受け取り、それが大文字・小文字のアルファベット、数値、空白、またはその他の文字であるかを判別するロジックを作成します。Pythonの文字列メソッドを活用した条件分岐の実装例です。


def classify_character(char):
    if len(char) != 1:
        return "1文字のみを入力してください"
        
    if char.isalpha():
        if char.isupper():
            return "大文字の英字です"
        elif char.islower():
            return "小文字の英字です"
    else:
        if char.isspace():
            return "空白文字です"
        elif char.isdigit():
            return "数字文字です"
        else:
            return "その他の文字です"

if __name__ == "__main__":
    input_char = input("1文字を入力してください: ")
    result = classify_character(input_char)
    print(f"判定結果: {result}")

3. 文字列の変換処理(数値漢字化とフォーマット)

入力文字列に対して、英字のみの単語を小文字化し、数字を含む単語内のアラビア数字を漢数字に変換します。さらに、すべての区切り文字をパーセント記号('%')に置換する処理を実装します。


def transform_string_data(source):
    # 数字から漢数字へのマッピングテーブル
    digit_map = str.maketrans('0123456789', '〇一二三四五六七八九')
    processed_tokens = []
    
    # スペース区切りでトークン化
    for token in source.split():
        # 英字のみの場合は小文字化
        if token.isalpha():
            token = token.lower()
        
        # 数字の変換を実行
        translated_token = token.translate(digit_map)
        processed_tokens.append(translated_token)
        
    # 区切り文字を'%'にして結合
    return '%'.join(processed_tokens)

if __name__ == "__main__":
    raw_text = input("文字列を入力してください: ")
    modified_text = transform_string_data(raw_text)
    print(f"変換後の文字列: {modified_text}")

4. 簡易的な文字列暗号化と復号化

シーザー暗号の変形として、各文字のASCIIコードに100から200の間のランダムな整数を加算する暗号化処理、およびその逆演算による復号化処理を実装します。


import random

def process_cipher(text, mode='encrypt'):
    shift = 150  # 固定シフト値(または random.randint(100, 200))
    result_chars = []
    
    for char in text:
        if mode == 'encrypt':
            # 暗号化: ASCIIコードにシフト値を加算
            new_val = ord(char) + shift
            result_chars.append(str(new_val))
        else:
            # 復号化: 文字列として格納されたコードを数値に戻しシフトを減算
            original_val = int(char) - shift
            result_chars.append(chr(original_val))
            
    separator = ' ' if mode == 'encrypt' else ''
    return separator.join(result_chars)

if __name__ == "__main__":
    original = input("平文を入力してください: ")
    encrypted = process_cipher(original, 'encrypt')
    print(f"暗号化結果(スペース区切り): {encrypted}")
    
    decrypted = process_cipher(encrypted, 'decrypt')
    print(f"復号化結果: {decrypted}")

5. 文字出現頻度の解析

与えられた文字列内で最も頻繁に出現する文字を特定します。辞書型(Dictionary)を用いてカウントを行うアルゴリズムです。


def find_most_frequent_char(text):
    frequency = {}
    
    # 出現回数をカウント
    for char in text:
        frequency[char] = frequency.get(char, 0) + 1
        
    if not frequency:
        return None, 0
        
    # 最大頻度を取得
    max_count = max(frequency.values())
    
    # 最大頻度を持つ文字を取得(複数ある可能性を考慮)
    most_frequent = [char for char, count in frequency.items() if count == max_count]
    
    return most_frequent, max_count

if __name__ == "__main__":
    sample_text = input("文字列を入力してください: ")
    chars, count = find_most_frequent_char(sample_text)
    print(f"最頻出文字: {chars} (出現回数: {count}回)")

6. 正規表現を用いたテキスト処理

以下の固定テキストデータを対象に、reモジュールを使用した様々な情報抽出タスクを実行します。
sample_data = "馬丽于2022-4-29 10:10刊发了一首诗《Listen to me》,诗词的大意是:\n Mama you taught me to do the right things,\n So now you have to let your baby fly.\n You've given me everything that I will need,\n To make it through this crazy thing called life,\n Thank you Mum!"

6-1. 数字と英字の存在確認

文字列内に数値(0-9)、小文字英字、大文字英字が含まれているかを正規表現で判定します。


import re

target = "馬丽于2022-4-29 10:10刊发了一首诗《Listen to me》,诗词的大意是:\n Mama you taught me to do the right things,\n So now you have to let your baby fly.\n You've given me everything that I will need,\n To make it through this crazy thing called life,\n Thank you Mum!"

def check_patterns(text):
    if re.search(r'[0-9]', text):
        print("数値(0-9)が含まれています")
    if re.search(r'[a-z]', text):
        print("小文字英字が含まれています")
    if re.search(r'[A-Z]', text):
        print("大文字英字が含まれています")

check_patterns(target)

6-2. 複数デリミタによる分割

中国語・英語の句読点、感嘆符、改行記号をデリミタとして文字列を分割します。


def split_by_delimiters(text):
    # 分割パターン: カンマ、ピリオド、感嘆符、改行
    pattern = r'[,.。!!\n]'
    fragments = re.split(pattern, text)
    
    # 空の要素を除外して表示
    clean_fragments = [f for f in fragments if f.strip()]
    print("分割結果:", clean_fragments)

split_by_delimiters(target)

6-3. 日時情報の抽出

「YYYY-M-D H:M」形式の日時文字列を抽出します。


def extract_datetime(text):
    match = re.search(r'(\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2})', text)
    if match:
        print(f"抽出された日時: {match.group(1)}")

extract_datetime(target)

6-4. 詩のタイトル抽出

鍵括弧『』で囲まれた部分を抽出します。


def extract_title(text):
    match = re.search(r'《(.+?)》', text)
    if match:
        print(f"詩のタイトル: {match.group(1)}")

extract_title(target)

6-5. 氏名の抽出

特定のキーワード(ここでは「于」)の直前にある文字列を氏名として抽出します。


def extract_name(text):
    # 「于」の直前の文字列を取得(肯定の先読みを使用)
    match = re.search(r'(.+?)(?=于)', text)
    if match:
        print(f"抽出された氏名: {match.group(1)}")

extract_name(target)

7月12日 22:27 投稿