:mod:`morastrja` --- 日本語のモーラ列の管理 ============================================ .. module:: morastrja .. testsetup:: * from morastrja import * from morastrja.utils import * __name__ = '' -------------- このモジュールは、日本語のモーラ列を扱うためのクラスと、それを支援するいくつかのユーティリティー関数を提供します。 ========================= ==================================================================== :func:`count_all` 仮名文字で構成された文字列に含まれるモーラ数を返す関数 :class:`MoraStr` モーラ列を文字列のように扱えるシーケンス型 :const:`CONVERSION_TABLE` 半角カタカナから全角カタカナへの変換テーブル :mod:`utils` モーラ分割の前処理に便利な関数群 ========================= ==================================================================== モジュール関数 -------------- .. function:: count_all(kana_string: str, /, *, ignore: bool = False) -> int 仮名文字で構成された文字列を受け取り、それに対応する音形に含まれるモーラ数を返すシンプルな関数です。 *ignore* オプションを指定することで、不要な文字を読み飛ばすことができます。\ 詳しくは、次節の :class:`MoraStr` オブジェクトの説明や例も参照してください。 例: .. doctest:: # モーラを数える >>> from morastrja import count_all >>> count_all('きゃりーぱみゅぱみゅ') 7 :class:`MoraStr` オブジェクト ----------------------------------------------- .. class:: MoraStr(kana_string: str|MoraStr = '', /, *, ignore: bool = False) 日本語の仮名文字列から、モーラ毎にランダムアクセス可能なシーケンスを構成します。 このクラスのコンストラクターは二つの引数を取ります。一つ目の引数は、日本語の仮名文字から成る文字列か :class:`MoraStr` オブジェクトのいずれかでなくてはなりません。全角カタカナ・ひらがな・半角カタカナ以外の文字が入力に含まれていた場合、エラーとなります。二\ つ目の引数は *ignore* オプションで、これがTrueに指定されていた場合、第一引数に渡された文字列に含まれる仮名文字以外の文字は\ 全て読み飛ばされ、エラーは生じません。 .. note:: 第一引数に渡される文字列中の全角カタカナとひらがなは、合成済み文字として正規化されている必要があります。つまり、濁点や半濁点を含む仮\ 名は単一のコードポイントとして表現されていなければなりません。 :class:`MoraStr` オブジェクトには、パブリックな属性として以下の2つのメンバーが存在します。 .. property:: length: int オブジェクトに含まれるモーラ数を取得します。 [1]_ morastr.length は len(morastr) と等価です。 .. property:: string: str 基底のカタカナ文字列を取得します。文字列に含まれる全ての文字は全角カタカナであることが保証されます。 また、 :class:`MoraStr` オブジェクトは、以下の表にあるシーケンス演算に対応しています。 sは仮名文字列か :class:`MoraStr` オブジェクト、n, i, j, kは整数を表します。 .. table:: :align: center +-----------------------+---------------------------------------+---------------+ | シーケンス演算 | 対応する特殊メソッドの呼び出し | 戻り値の型 | +=======================+=======================================+===============+ | ``s in morastr`` [1]_ | ``morastr.__contains__(s)`` |*bool* | +-----------------------+---------------------------------------+---------------+ | ``s not in morastr`` | ``not morastr.__contains__(s)`` |*bool* | +-----------------------+---------------------------------------+---------------+ | ``morastr + s`` | ``morastr.__add__(s)`` |*type(morastr)*| +-----------------------+---------------------------------------+---------------+ | ``morastr * n`` | ``morastr.__mul__(n)`` |*type(morastr)*| +-----------------------+---------------------------------------+---------------+ | ``n * morastr`` | ``morastr.__rmul__(n)`` |*type(morastr)*| +-----------------------+---------------------------------------+---------------+ | ``morastr[i]`` | ``morastr.__getitem__(i)`` |*str* | +-----------------------+---------------------------------------+---------------+ | ``morastr[i:j]`` | ``morastr.__getitem__(slice(i,j))`` |*type(morastr)*| +-----------------------+---------------------------------------+---------------+ | ``morastr[i:j:k]`` | ``morastr.__getitem__(slice(i,j,k))`` |*type(morastr)*| +-----------------------+---------------------------------------+---------------+ | ``len(morastr)`` | ``morastr.__len__()`` |*int* | +-----------------------+---------------------------------------+---------------+ 次に示すのは、基本的な使用例です。 .. doctest:: # MoraStrクラスをインポート >>> from morastrja import MoraStr # インスタンスの作成 >>> MoraStr('モーラ') MoraStr('モ' 'ー' 'ラ') >>> MoraStr('ひらがな') MoraStr('ヒ' 'ラ' 'ガ' 'ナ') >>> MoraStr('ハンカクモジ') MoraStr('ハ' 'ン' 'カ' 'ク' 'モ' 'ジ') # 拗音類 >>> MoraStr('トーキョー') MoraStr('ト' 'ー' 'キョ' 'ー') >>> MoraStr('ティッシュ') MoraStr('ティ' 'ッ' 'シュ') >>> MoraStr('シミュレーション') MoraStr('シ' 'ミュ' 'レ' 'ー' 'ショ' 'ン') # 仮名文字以外はエラー (ignoreオプションで読み飛ばせる) >>> MoraStr('漢字') Traceback (most recent call last): ... ValueError: invalid character: '漢' (u+6f22) >>> MoraStr('漢字が難しい', ignore=True) MoraStr('ガ' 'シ' 'イ') >>> MoraStr(' モジ ') # 仮名文字の前後に空白 Traceback (most recent call last): ... ValueError: invalid character: ' ' (u+0020) >>> MoraStr(' モジ ', ignore=True) MoraStr('モ' 'ジ') # モーラ数を取得 >>> len(MoraStr('モーラ')) 3 >>> len(MoraStr('シミュレーション')) 6 # .length属性でも取得可 >>> MoraStr('シミュレーション').length 6 # モーラ数だけでいいなら、count_all()が高速 >>> MoraStr.count_all('チューリップ') 5 # .string属性で、正規化されたプレーンな文字列を取得 >>> m = MoraStr('コンピューター') >>> m MoraStr('コ' 'ン' 'ピュ' 'ー' 'タ' 'ー') >>> m.string 'コンピューター' >>> type(m.string) # 添え字アクセス >>> MoraStr('アーティキュレーション')[3] 'キュ' >>> 'アーティキュレーション'[3] # 参考 'ィ' >>> MoraStr('アーティキュレーション')[-2] 'ショ' # 範囲外はエラー >>> MoraStr('アーティキュレーション')[8] Traceback (most recent call last): ... IndexError: MoraStr index out of range >>> MoraStr('アーティキュレーション')[-9] Traceback (most recent call last): ... IndexError: MoraStr index out of range # スライス >>> MoraStr('シチュエーション')[:2] MoraStr('シ' 'チュ') >>> MoraStr('アルバイト')[-3:] MoraStr('バ' 'イ' 'ト') >>> MoraStr('ノートルダムジョガクイン')[4:7] MoraStr('ダ' 'ム' 'ジョ') # 内容の書き換えは不可。イミュータブル >>> m = MoraStr('オブジェクト') >>> m[0] = 'サ' Traceback (most recent call last): ... TypeError: 'morastr.MoraStr' object does not support item assignment >>> m = MoraStr('オーストラリア') >>> del m[-3] Traceback (most recent call last): ... TypeError: 'morastr.MoraStr' object doesn't support item deletion # ハッシュ可能。辞書のキーとして使える >>> key = MoraStr('キー') >>> mapping = {} >>> mapping[key] = MoraStr('バリュー') >>> MoraStr('キー') in mapping True # 等価性の判定: .string属性同士が比較される >>> MoraStr('もじれつ') == MoraStr('モジレツ') == MoraStr('モジレツ') True >>> MoraStr('クラス') == MoraStr('グラス') False >>> MoraStr('バレエ') == MoraStr('バレー') False # 文字列との比較は、同じ内容であってもFalseとなる >>> MoraStr('モジレツ') == 'モジレツ' False # 順序比較は定義されていない >>> MoraStr('カー') < MoraStr('カイ') Traceback (most recent call last): ... TypeError: '<' not supported between instances of ... >>> MoraStr('はつか') > MoraStr('はっか') Traceback (most recent call last): ... TypeError: '>' not supported between instances of ... # 部分モーラ列判定 (in) >>> 'シャ' in MoraStr('ショーシャマン') True >>> 'シ' in MoraStr('ショーシャマン') False >>> 'パンキョー' in MoraStr('イッパンキョーヨー') True >>> 'パンキ' in MoraStr('イッパンキョーヨー') False # +演算子: MoraStrオブジェクトを結合して新しいオブジェクトを返す >>> MoraStr('トーキョー') + MoraStr('スカイツリー') MoraStr('ト' 'ー' 'キョ' 'ー' 'ス' 'カ' 'イ' 'ツ' 'リ' 'ー') >>> MoraStr('ジェット') + MoraStr('エンジン') MoraStr('ジェ' 'ッ' 'ト' 'エ' 'ン' 'ジ' 'ン') # 繰り返し >>> MoraStr('オラ') * 8 MoraStr('オ' 'ラ' 'オ' 'ラ' 'オ' 'ラ' 'オ' 'ラ' 'オ' 'ラ' 'オ' 'ラ' 'オ' 'ラ' 'オ' 'ラ') # イテレーターの取得 >>> it = iter(MoraStr('あしゅら')) >>> next(it) 'ア' >>> next(it) 'シュ' >>> next(it) 'ラ' >>> next(it) Traceback (most recent call last): ... StopIteration # for文で回す >>> for m in MoraStr('バーチャル'): ... print(m) ... バ ー チャ ル # リスト化 >>> list(MoraStr('シュレッダー')) ['シュ', 'レ', 'ッ', 'ダ', 'ー'] >>> [*MoraStr('シュレッダー')] # 上と同じ ['シュ', 'レ', 'ッ', 'ダ', 'ー'] # 逆順にイテレート >>> r = reversed(MoraStr('チョコレート')) >>> next(r); next(r); next(r); next(r); next(r) 'ト' 'ー' 'レ' 'コ' 'チョ' # 反転したオブジェクトはm[::-1]で生成できる >>> MoraStr('チョコレート')[::-1] MoraStr('ト' 'ー' 'レ' 'コ' 'チョ') # repr()で得た文字列表現をeval()したものは、元のオブジェクトと等価 >>> m = MoraStr('モーラ') >>> eval(repr(m)) == m True # 参照: https://docs.python.org/ja/3.11/library/functions.html#eval # 直列化 (pickle化) >>> import pickle >>> m1 = MoraStr('チョクレツカ') >>> p = pickle.dumps(m1) >>> m2 = pickle.loads(p) >>> m2 MoraStr('チョ' 'ク' 'レ' 'ツ' 'カ') >>> m1 == m2 True .. classmethod:: fromstrs(cls: type[Self], *iterable: Iterable[str], ignore: bool = False) -> Self 複数のカタカナ文字列から、一つの :class:`MoraStr` オブジェクトを生成する代替的なコンストラクタです。任意の数の文字\ 列、あるいは文字列のイテラブルを引数として取ります。キーワード引数は、通常のコンストラクタと同じように扱われます。 概ね、次のコードと等価です:: @classmethod def fromstrs(cls, *iterables, **kwargs): return cls(''.join(''.join(it) for it in iterables), **kwargs) 例: .. doctest:: # 複数の文字列からインスタンスを作成 >>> MoraStr.fromstrs('シゼン', 'カンキョー', 'ホゴ') MoraStr('シ' 'ゼ' 'ン' 'カ' 'ン' 'キョ' 'ー' 'ホ' 'ゴ') # 文字列のリストから >>> MoraStr.fromstrs(['カンセンショー', 'カクダイ', 'ボーシ']) MoraStr('カ' 'ン' 'セ' 'ン' 'ショ' 'ー' 'カ' 'ク' 'ダ' 'イ' 'ボ' 'ー' 'シ') # リストに限らず、任意のリテラブルを受け取れる >>> seasons = {'ハル': 'spring', 'ナツ': 'summer', 'アキ': 'autumn', 'フユ': 'winter'} >>> MoraStr.fromstrs(seasons) MoraStr('ハ' 'ル' 'ナ' 'ツ' 'ア' 'キ' 'フ' 'ユ') # イテラブルは複数でも可 >>> MoraStr.fromstrs(['キョー', 'ワ'], ['イー'], ['テンキ', 'デス']) MoraStr('キョ' 'ー' 'ワ' 'イ' 'ー' 'テ' 'ン' 'キ' 'デ' 'ス') # MoraStr()と同じく、ignoreオプションで無効な文字を読み飛ばせる。 >>> MoraStr.fromstrs([' サンショーウオ🐡', 'ワ'], ['カナシンダ😢。'], ignore=True) MoraStr('サ' 'ン' 'ショ' 'ー' 'ウ' 'オ' 'ワ' 'カ' 'ナ' 'シ' 'ン' 'ダ') .. staticmethod:: count_all(kana_string: str, /, *, ignore: bool = False) -> int モジュール関数 :func:`count_all` と同じです。\ 仮名文字列を受け取り、それに対応する音形に含まれるモーラ数を返します。 ``len(MoraStr(kana_string))`` とも概ね同じですが、こちらの関数の方が余分な中間オブジェクトを生成しない\ 分、高速です。第一引数は文字列型のみが指定可能です。 ``MoraStr()`` と同じく、 *ignore* オプションを指定する\ ことで、不要な文字を読み飛ばすことができます。 例: .. doctest:: # モーラを数える >>> MoraStr.count_all('きゃりーぱみゅぱみゅ') 7 # 仮名文字以外を読み飛ばす >>> MoraStr.count_all('I am ジュンヤ.', ignore=True) 3 .. method:: char_indices(*, zero: bool = False) -> list[int] モーラ毎の文字数の累積和を整数のリストで返します。 *zero* オプションを True に設定すると、戻り値の累積和リストが\ 0始まりになります。 例: .. doctest:: # モーラ毎の文字数の累積和をリストで返す >>> MoraStr('アクションシューティング').char_indices() [1, 2, 4, 5, 7, 8, 10, 11, 12] # zeroオプションでリストの先頭に0が挿入される >>> MoraStr('アクションシューティング').char_indices(zero=True) [0, 1, 2, 4, 5, 7, 8, 10, 11, 12] .. method:: count(sub_morastr: str|MoraStr, start: int|SupportsIndex|None = 0, end: int|SupportsIndex|None = None, /) -> int ``self[start:end]`` の範囲内に部分モーラ列 *sub_morastr* が現れる回数を返します [2]_ 。 *sub_morastr* は、仮名文字列か :class:`MoraStr` オブジェクトでなくてはなりません。\ もしも *start* が *sub_morastr* の長さを超えていた場合は0が返されます。 例: .. doctest:: # 部分モーラ列を数える >>> MoraStr('すもももももももものうち').count('も') 8 >>> MoraStr('ししょしつ').count('し') 2 # 第二引数 (start)、第三引数 (end) で範囲を限定 >>> m = MoraStr('どじょーにょろにょろみにょろにょろ') >>> m.count('にょろ', 7) # == m[7:].count('にょろ') 2 >>> m.count('にょろ', 3, 10) # == m[3:10].count('にょろ') 3 >>> m = MoraStr('トーキョートッキョキョカキョク') >>> m.count('キョ', -4) # == m[-4:].count('キョ') 2 .. method:: endswith(suffix: str|MoraStr|tuple[str|MoraStr], start: int|SupportsIndex|None = 0, end: int|SupportsIndex|None = None, /) -> bool ``str.endswith()`` と似ていますが、引数はモーラ単位で解釈されます。 例: .. doctest:: # str.endswithとほぼ同じ >>> MoraStr('アルバイト').endswith('バイト') True # 第二引数(start)と第三引数(end)で範囲をモーラ単位で指定 >>> MoraStr('クリスチャン').endswith('クリス', 0, -2) True >>> MoraStr('ジュンイチ').endswith('イチ', 3) False # 第一引数にはタプルも指定可能。いずれかに一致すればTrue >>> MoraStr('アンパンマン').endswith(('セン', 'マン', 'オク')) True >>> MoraStr('セバスチャン').endswith(('クン', 'サン', 'サマ')) False .. method:: find(sub_morastr: str|MoraStr, /, *, charwise: bool = False) -> int find(sub_morastr: str|MoraStr, start: int|SupportsIndex|None = 0, end: int|SupportsIndex|None = None, /) -> int :class:`MoraStr` オブジェクト内で、最初に *sub_morastr* が見つかった位置をモーラ単位で返します。\ *start/end* 引数はスライスとして解釈されますが、 *start* 引数を指定した場合に返されるインデックスは *start* を起点として数えたものではなく、文字列全体から見たものになります。 *start* が ``len(self)`` を超えているか、 *sub_morastr* が見つからなかった場合には、-1を返します。 *charwise* オプションを \ True に設定すると、 *sub_morastr* の位置インデックスをモーラ単位ではなく文字数単位で返すようになります。 \ *charwise* オプションは、 *start/end* が指定されていない場合にのみ有効です。 例: .. doctest:: # 部分モーラ列のインデックス(0始まり)をモーラ単位で返す >>> MoraStr('チューオーチ').find('チ') 4 >>> MoraStr('ジュージュンメ').find('ジュン') 2 # 見つからなかった場合は-1 >>> MoraStr('シャンソンカシュ').find('シ') -1 # 第二引数 (start)、第三引数 (end) で範囲を限定 >>> MoraStr('チイキジチ').find('チ', 3) 4 >>> MoraStr('シュンカシュートー').find('シュ', 2) 3 >>> MoraStr('ディーブイディー').find('ディー', 2, 4) -1 # charwiseオプションを指定すると、当該モーラの位置を文字単位で返す >>> MoraStr('シュンジュージダイ').find('ジ') 4 >>> MoraStr('シュンジュージダイ').find('ジ', charwise=True) 6 # start/end引数と、charwise引数を同時に指定するとエラー >>> MoraStr('センゴクジダイ').find('ジ', 4, charwise=True) Traceback (most recent call last): ... TypeError: ... .. method:: finditer(sub_morastr: str|MoraStr, /, *, charwise: bool = False) -> Iterator[int] ``self`` 内で *sub_morastr* が現れる位置を yield するイテレーターを返します [2]_ 。 *sub_morastr* は仮名文字列か :class:`MoraStr` オブジェクトでなければなりません。\ *sub_morastr* が ``self`` よりも長い場合(モーラ数が多い場合)、スワップした後に\ 検索が行われます。つまり、長いモーラ列内を短いモーラ列で検索した結果を yield します。\ *charwise* オプションを指定すると、位置インデックスはモーラ数ではなく文字数を元に算出されます。 例: .. doctest:: # モーラ列が現れる位置をyieldするイテレーターを返す >>> it = MoraStr('シュンキデシュッシシューリョー').finditer('シュ') >>> next(it) 0 >>> next(it) 4 >>> next(it) 7 >>> next(it) Traceback (most recent call last): ... StopIteration # 「何モーラ目か」ではなく「何文字目か」を知りたい場合は、charwiseオプションを指定する >>> it = MoraStr('シュンキデシュッシシューリョー').finditer('シュ', charwise=True) >>> list(it) # リスト化 [0, 5, 9] # レシーバーよりも引数の方が長い場合、レシーバーと引数をスワップしてから検索が行われる # つまり、レシーバーと引数のうち「長い方」の中から「短い方」を検索する >>> it = MoraStr('シュ').finditer('シュンキデシュッシシューリョー') >>> for pos in it: print(pos) ... 0 4 7 .. method:: index(sub_morastr: str|MoraStr, /, *, charwise: bool = False) -> int index(sub_morastr: str|MoraStr, start: int|SupportsIndex|None = 0, end: int|SupportsIndex|None = None, /) -> int :meth:`MoraStr.find` と大体同じですが、モーラ列が見つからなかったときに -1ではなく\ ``IndexError`` を返します。 例: .. doctest:: # MoraStr.find()とほぼ同じだが、見つからなかった場合にはエラーを返す >>> MoraStr('チューオーチ').index('チ') 4 >>> MoraStr('ジュージュンメ').index('ジュン') 2 >>> MoraStr('シャンソンカシュ').index('シ') Traceback (most recent call last): ... ValueError: submora-string not found >>> MoraStr('チイキジチ').index('チ', 3) 4 >>> MoraStr('シュンカシュートー').index('シュ', 2) 3 >>> MoraStr('ディーブイディー').index('ディー', 2, 4) Traceback (most recent call last): ... ValueError: submora-string not found >>> MoraStr('シュンジュージダイ').index('ジ') 4 >>> MoraStr('シュンジュージダイ').index('ジ', charwise=True) 6 >>> MoraStr('センゴクジダイ').index('ジ', 4, charwise=True) Traceback (most recent call last): ... TypeError: ... .. method:: removeprefix(prefix: str|MoraStr, /) -> MoraStr ``self`` が *prefix* で始まっていたなら、 ``self[len(prefix):]`` を返し、\ そうでないなら、元のオブジェクトのコピーを返します。 例: .. doctest:: # MoraStrオブジェクトが指定されたモーラ列で始まっていたら、その部分を削除したモーラ列を返す >>> MoraStr('メッシュキジ').removeprefix('メッシュ') MoraStr('キ' 'ジ') # 先頭のモーラ列が一致しない場合、元と等価なオブジェクトを返す >>> MoraStr('メッシュキジ').removeprefix('メッシ') MoraStr('メ' 'ッ' 'シュ' 'キ' 'ジ') .. method:: removesuffix(suffix: str|MoraStr, /) -> MoraStr ``self`` が *suffix* で終わっていたなら\ ``morastr[:len(morastr)-len(suffix)]`` を返し、そうでないなら、\ 元のオブジェクトのコピーを返します。 例: .. doctest:: # MoraStrオブジェクトが指定されたモーラ列で終わっていたら、その部分を削除したモーラ列を返す >>> MoraStr('リンゴジュース').removesuffix('ジュース') MoraStr('リ' 'ン' 'ゴ') # 末尾のモーラ列が一致しない場合、元と等価なオブジェクトを返す >>> MoraStr('リンゴジャム').removesuffix('ジュース') MoraStr('リ' 'ン' 'ゴ' 'ジャ' 'ム') .. method:: replace(old: str|MoraStr, new: str|MoraStr, maxcount: int|SupportsIndex = -1) -> MoraStr :class:`MoraStr` オブジェクト中の部分モーラ列 *old* を *new* で置き換えた新しいオブジェクトを\ 返します。 *maxcount* を非負数に設定した場合、左から順にその回数だけ置換が行われます。 例: .. doctest:: # 第一引数のモーラを第二引数のモーラで置き換えた新しいモーラ列を返す >>> MoraStr('カンカンカン').replace('カ', 'コ') MoraStr('コ' 'ン' 'コ' 'ン' 'コ' 'ン') >>> MoraStr('ドンドンドンドン').replace('ド', 'ビュ') MoraStr('ビュ' 'ン' 'ビュ' 'ン' 'ビュ' 'ン' 'ビュ' 'ン') >>> MoraStr('にゃんにゃんにゃん').replace('にゃ', 'わ') MoraStr('ワ' 'ン' 'ワ' 'ン' 'ワ' 'ン') >>> MoraStr('チョロチョロ').replace('チョ', 'ジョ') MoraStr('ジョ' 'ロ' 'ジョ' 'ロ') >>> m = MoraStr('かえるぴょこぴょこみぴょこぴょこ') >>> m.replace('かえる', 'どじょう').replace('ぴょこ', 'にょろ') MoraStr('ド' 'ジョ' 'ウ' 'ニョ' 'ロ' 'ニョ' 'ロ' 'ミ' 'ニョ' 'ロ' 'ニョ' 'ロ') # 第一引数の部分モーラ列が見つからない場合は、元と同じモーラ列を返す >>> MoraStr('チョロチョロ').replace('チ', 'キ') MoraStr('チョ' 'ロ' 'チョ' 'ロ') # 置換回数を指定 >>> MoraStr('オラオラオラオラオラオラオラオラ').replace('オラ', 'ムダ', 5) MoraStr('ム' 'ダ' 'ム' 'ダ' 'ム' 'ダ' 'ム' 'ダ' 'ム' 'ダ' 'オ' 'ラ' 'オ' 'ラ' 'オ' 'ラ') .. method:: rfind(sub_morastr: str|MoraStr, /, *, charwise: bool = False) -> int rfind(sub_morastr: str|MoraStr, start: int|SupportsIndex|None = 0, end: int|SupportsIndex|None = None, /) -> int :class:`MoraStr` オブジェクト内で、最後に *sub_morastr* が見つかった位置をモーラ単位で返します。\ *start* が ``len(self)`` を超えているか、 *sub_morastr* が見つからなかった場合には、\ -1を返します。 *start/end* 引数はスライスとして解釈されますが、 *start* 引数を指定した場合に\ 返されるインデックスは *start* を起点として数えたものではなく、文字列全体から見たものになります。 *charwise* オプションを True に設定すると、 *sub_morastr* が見つかった位置をモーラ単位ではなく\ 文字数単位で返します。 *charwise* オプションは、 *start/end* が指定されていない場合にのみ有効です。 例: .. doctest:: # 部分モーラ列を逆順に検索 >>> MoraStr('ソツギョーショーショ').rfind('ショ') 6 >>> MoraStr('ソツギョーショーショ').rfind('ショー') 4 # 見つからなかった場合は-1 >>> MoraStr('ソツギョーショーショ').rfind('シ') -1 # 第二引数 (start)、第三引数 (end) で範囲を限定 >>> MoraStr('ソツギョーショーショ').rfind('ショ', 2, 6) 4 >>> MoraStr('ソツギョーショーショ').rfind('ギョ', 4) -1 # charwiseオプションを指定すると、当該モーラの位置を文字単位で返す >>> MoraStr('ソツギョーショーショ').rfind('ショ', charwise=True) 8 >>> MoraStr('ソツギョーショーショ').rfind('ショー', charwise=True) 5 # start/end引数と、charwise引数を同時に指定するとエラー >>> MoraStr('ソツギョーショーショ').rfind('ギョ', 4, charwise=True) Traceback (most recent call last): ... TypeError: ... .. method:: rindex(sub_morastr: str|MoraStr, /, *, charwise: bool = False) -> int rindex(sub_morastr: str|MoraStr, start: int|SupportsIndex|None = 0, end: int|SupportsIndex|None = None, /) -> int :meth:`MoraStr.rfind` と大体同じですが、モーラ列が見つからなかったときに -1ではなく\ ``IndexError`` を返します。 例: .. doctest:: # MoraStr.rfind()とほぼ同じだが、見つからなかった場合にはエラーを返す >>> MoraStr('ゴミシューシューシャ').rindex('シュ') 4 >>> MoraStr('ゴミシューシューシャ').rindex('シャー') Traceback (most recent call last): ... ValueError: submora-string not found # 第二引数 (start)、第三引数 (end) で範囲を限定 >>> MoraStr('ゴミシューシューシャ').rindex('シュー', 0, 5) 2 >>> MoraStr('ゴミシューシューシャ').rindex('ゴミ', 2) Traceback (most recent call last): ... ValueError: submora-string not found # charwiseオプションを指定すると、当該モーラの位置を文字単位で返す >>> MoraStr('ゴミシューシューシャ').rindex('シャ', charwise=True) 8 >>> MoraStr('ゴミシューシューシャ').rindex('シュー', charwise=True) 5 # start/end引数と、charwise引数を同時に指定するとエラー >>> MoraStr('ゴミシューシューシャ').rindex('ゴミ', 2, charwise=True) Traceback (most recent call last): ... TypeError: ... .. method:: startswith(prefix: str|MoraStr|tuple[str|MoraStr], start: int|SupportsIndex|None = 0, end: int|SupportsIndex|None = None, /) -> bool ``str.startswith()`` と似ていますが、引数はモーラ単位で解釈されます。 例: .. doctest:: # MoraStrオブジェクトが、指定したモーラ列で始まるかどうかを判定 >>> MoraStr('マッチャアイス').startswith('マッチャ') True >>> MoraStr('マッチャアイス').startswith('マッチ') False # 第二引数(start)と第三引数(end)で範囲をモーラ単位で指定 >>> MoraStr('アオリンゴジュース').startswith('リンゴ', 2) True >>> MoraStr('ナツミカンゼリー').startswith('ミカンゼリー', 2, -3) False # 第一引数にはタプルも指定可能。いずれかに一致すればTrue >>> MoraStr('バナナパフェ').startswith(('イチゴ', 'バナナ', 'マッチャ')) True >>> MoraStr('カボチャパフェ').startswith(('イチゴ', 'バナナ', 'マッチャ')) False .. method:: tostr() -> str オブジェクト内部の文字列表現を返します。 [1]_ morastr.tostr() は morastr.string と等価です。 .. doctest:: # 複数のMoraStrオブジェクトをまとめてstr型に戻す >>> morastr_list = [MoraStr('いち'), MoraStr('に'), MoraStr('さん')] >>> [*map(MoraStr.tostr, morastr_list)] ['イチ', 'ニ', 'サン'] 内部データ ---------- .. data:: CONVERSION_TABLE 半角カタカナがどのように全角カタカナにマッピングされるかを示した読み取り専用の辞書です。 :func:`count_all` 関数や :class:`MoraStr` オブジェクトのメソッドの引数処理に使われます。\ 実行中に書き換えることはできませんが、 :mod:`morastrja` モジュールがインストールされている\ ディレクトリにある *data/table.py* を編集することで、次回起動時以降の振る舞いをカスタマイズすることができます。 :mod:`utils` サブモジュール ----------------------------------------------- .. module:: utils ユーティリティー関数 .. function:: vowel_to_choon(kana_string: str, /, maxrep: int = 1, *, clean: bool = False, ou: bool = False, ei: bool = False, nn: bool = True) -> str vowel_to_choon(kana_string: MoraStr, /, maxrep: int = 1, *, clean: bool = False, ou: bool = False, ei: bool = False, nn: bool = True) -> MoraStr 連続する同一母音を長音符(ー)で置き換えた文字列(あるいは :class:`~morastrja.MoraStr` オブジェクト)を\ 返します。入力の文字列は、全角カタカナで構成されているものと仮定されます。戻り値の型は、関数に対し str かそのサブタイプが\ 渡されたなら str となり、 :class:`~morastrja.MoraStr` オブジェクトか、 :class:`~morastrja.MoraStr` を継承したクラスのインスタンスが渡された場合は、 :class:`~morastrja.MoraStr` 型となります。 *maxrep* オプション (デフォルトは1)で長音符の連続を\ いくつまで許容するかを設定できます。 *clean* オプションが True の場合、出力から仮名以外の文字が全て除去されます。\ また、 *ou* を True に設定することで「オ段+ウ」を、 *ei* を True に設定することで「エ段+イ」を、\ それぞれ長音符表記に置き換えることができます。キーワード *nn* は、連続する撥音(ン)を長音符で置き換えるかどうかを制御します。\ デフォルトは **True** です。 例: .. doctest:: # utilsサブモジュールから使用できる >>> from morastrja.utils import vowel_to_choon # カタカナ文字列中の同一母音の連続を長音符(ー)に置き換える >>> vowel_to_choon('オオドオリ') 'オードーリ' # ひらがなや半角カタカナのものは置き換えられないことに注意 >>> vowel_to_choon('おおどおり') 'おおどおり' # 同一母音が三つ以上連続する場合は、偶数番目のもののみが置き換えられる >>> vowel_to_choon('アアアアアアアア') 'アーアーアーアー' >>> vowel_to_choon('オオオカエチゼン') 'オーオカエチゼン' # maxrepオプションで、長音符の連続をいくつまで許容するかが指定できる >>> vowel_to_choon('エエエエエエエエエエエエエエエエ', maxrep=3) 'エーーーエーーーエーーーエーーー' # maxrepに-1を指定すると、際限なく置換される >>> vowel_to_choon('エエエエエエエエエエエエエエエエ', maxrep=-1) 'エーーーーーーーーーーーーーーー' # 元の文字列に既に長音符が含まれていた場合、maxrepを超えて長音符が連続することがある >>> vowel_to_choon('エエエエエエエエーーーエエエエ', maxrep=3) 'エーーーエーーーーーーエーーー' # また、maxrepの値を大きくしても既存の長音のブロックが融合されるわけではないことに注意 >>> s = vowel_to_choon('エーーーーエーーーーー', maxrep=10) >>> s # 'エーーーーーーーーーー'にはならない 'エーーーーエーーーーー' # デフォルトでは撥音(ン)の連続も長音符に置き換えられる >>> vowel_to_choon('ンン') 'ンー' # 撥音を長音符に置き換えないようにするには、nnオプションをFalseに設定する >>> vowel_to_choon('ンン', nn=False) 'ンン' # ouオプションを指定すると、同一母音の連続に加えて「オ段+ウ」も長音符表記される >>> vowel_to_choon('トウキョウ', ou=True) 'トーキョー' # eiオプションを指定すると、「エ段+イ」も長音符表記される >>> vowel_to_choon('ケイエイ', ei=True) 'ケーエー' # cleanオプションを指定すると、出力から仮名以外の文字が全て除去される >>> vowel_to_choon('☆カナモジ★漢字', clean=True) 'カナモジ' # その際、ひらがな・半角カタカナは全て全角カタカナに置き換えられる >>> vowel_to_choon('ひらがなカタカナハンカク漢字', clean=True) 'ヒラガナカタカナハンカク' **注意:** *clean* オプションによる置換は、長音符の置き換えの後に適用されることに注意してください。 .. doctest:: >>> vowel_to_choon('おおどおりのオオカミ', clean=True) 'オオドオリノオーカミ' # 1. カタカナ部分を長音符表記に 'おおどおりのオオカミ' → 'おおどおりのオーカミ' # 2. 残りを全角カタカナに正規化 'おおどおりのオーカミ' → 'オオドオリノオーカミ' .. function:: choon_to_vowel(kana_string: str, /, *, strict: bool = True, clean: bool = False) -> str choon_to_vowel(kana_string: MoraStr, /, *, strict: bool = True, clean: bool = False) -> MoraStr 長音符(ー)を同一母音の連続に置き換えた文字列(あるいは :class:`~morastrja.MoraStr` オブジェクト)を\ 返します。入力の文字列は、全角カタカナで構成されているものと仮定されます。 :func:`vowel_to_choon` と\ 概ね逆の処理になりますが、 ``vowel_to_choon(choon_to_vowel(kana_string))`` が必ずしも\ 元のオブジェクトと等価になるとは限りません。。戻り値の型は、関数に対し str かそのサブタイプが\ 渡されたなら str となり、 :class:`~morastrja.MoraStr` オブジェクトか、 :class:`~morastrja.MoraStr` を継承したクラスのインスタンスが渡された場合は、 :class:`~morastrja.MoraStr` 型となります。長音符が全角カタカナ以外の文字の直後に現れたり、\ 母音や撥音に変換できなかったりした場合には ValueError が送出されます。キーワード *strict* を\ False に設定すると、不適切な長音符は手付かずのまま残り、エラーは生じません。 *clean* を True に\ すると、全角カタカナ以外の全ての文字が除去されます。ですので、その戻り値は :class:`~morastrja.MoraStr` クラスのコンストラクターに安全に渡すことができます。 例: .. doctest:: # utilsサブモジュールから使用できる >>> from morastrja.utils import choon_to_vowel # カタカナ文字列中の長音符(ー)を同一母音の連続に置き換える >>> choon_to_vowel('ポケモンセンターオーサカ') 'ポケモンセンタアオオサカ' # 撥音(ン)の直後の長音符も置換される >>> choon_to_vowel('ンーモッツァ') 'ンンモッツァ' # 全角カタカナ以外の文字の直後の長音符は置き換えられず、エラーとなる >>> choon_to_vowel('そーゆーこと') Traceback (most recent call last): ... ValueError: ... # 全角カタカナであっても、促音(ッ)の直後の長音符はエラーとなる >>> choon_to_vowel('アッー') Traceback (most recent call last): ... ValueError: ... # strictオプションをFalseにすると、エラーは発生せず無視される # その場合も置換は行われない >>> choon_to_vowel('そーゆーこと', strict=False) 'そーゆーこと' # cleanオプションを指定すると、出力から仮名以外の文字が全て除去される # その際、ひらがな・半角カタカナは全て全角カタカナに置き換えられる >>> choon_to_vowel('ひらがな☆カタカナ★ハンカク♪漢字', clean=True) 'ヒラガナカタカナハンカク' **注意:** *clean* オプションによる置換は、エラーチェックや長音符の置き換えの後に適用されることに注意してください。 .. doctest:: >>> choon_to_vowel('エラーなし', clean=True) 'エラアナシ' >>> choon_to_vowel('えらーアリ', clean=True) Traceback (most recent call last): ... ValueError: ... :func:`vowel_to_choon` も参照 .. rubric:: Footnotes .. [1] 小文字の morastr は任意の :class:`MoraStr` オブジェクトを指します。 .. [2] マッチした部分同士がオーバーラップすることはありません。これは組み込みの文字列型と同じ振舞いです。