# utils/name_splitter.py from typing import Tuple class NameSplitter: """ 日本語の氏名を扱うユーティリティクラス """ def split_full_name(self, full_name: str) -> Tuple[str, str]: """ フルネームを姓と名に分割する Args: full_name: 分割する氏名(例: '山田 太郎' or '山田 太郎' or 'Yamada Taro') Returns: (姓, 名)のタプル。分割できない場合は(フルネーム, '')を返す """ if not full_name: return ('', '') try: # 空白文字で分割(半角スペース、全角スペース、タブなど) parts = full_name.replace(' ', ' ').split() if len(parts) >= 2: last_name = parts[0] first_name = ' '.join(parts[1:]) # 名が複数単語の場合に対応 return (last_name.strip(), first_name.strip()) else: # 分割できない場合は全体を姓とする return (full_name.strip(), '') except Exception: return (full_name.strip(), '') def join_name(self, last_name: str, first_name: str, format_type: str = 'ja') -> str: """ 姓と名を結合して一つの文字列にする Args: last_name: 姓 first_name: 名 format_type: 出力形式 ('ja': 日本語形式, 'en': 英語形式) Returns: 結合された氏名文字列 """ last_name = last_name.strip() first_name = first_name.strip() if not last_name and not first_name: return '' if not first_name: return last_name if not last_name: return first_name if format_type == 'ja': return f"{last_name} {first_name}" # 全角スペース elif format_type == 'en': return f"{first_name} {last_name}" # 英語形式:名 姓 else: return f"{last_name} {first_name}" # デフォルト:半角スペース def normalize_name(self, name: str) -> str: """ 名前の正規化を行う Args: name: 正規化する名前文字列 Returns: 正規化された名前文字列 """ if not name: return '' # 空白文字の正規化 name = ' '.join(name.split()) # 連続する空白を単一の半角スペースに # 全角英数字を半角に変換 name = name.translate(str.maketrans({ ' ': ' ', # 全角スペースを半角に '.': '.', ',': ',', '!': '!', '?': '?', ':': ':', ';': ';', })) return name.strip() def is_valid_name(self, name: str) -> bool: """ 名前が有効かどうかをチェックする Args: name: チェックする名前文字列 Returns: 名前が有効な場合はTrue、そうでない場合はFalse """ if not name or not name.strip(): return False # 最小文字数チェック if len(name.strip()) < 2: return False # 記号のチェック(一般的でない記号が含まれていないか) invalid_chars = set('!@#$%^&*()_+=<>?/\\|~`') if any(char in invalid_chars for char in name): return False return True