Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで文字列が部分文字列の繰り返しかどうかを判定する方法

ある文字列が、その文字列自身の一部(部分文字列)の繰り返しのみで構成されているかどうかを確認したいケースはよくあります。例えば「abcabcabc」は「abc」の繰り返しですが、「abcdabc」はそうではありません。

このような判定には、文字列を2つ連結した中に、元の文字列の「回転」が含まれるかどうかを調べる方法が有効です。これは「文字列が周期的であるのは、それが自分自身の自明でない回転と一致するとき、かつそのときに限る」という性質に基づいています。

コード例

以下のコードは、繰り返し単位(周期)を検出し、見つかった場合はその部分文字列を、見つからない場合は None を返します。

def find_period(s):
    # s を2回連結した文字列の中から、
    # インデックス1以降〜末尾の手前までの範囲で s を検索する
    i = (s + s).find(s, 1, -1)
    return None if i == -1 else s[:i]

print(find_period('012012012012012'))
print(find_period('some random string'))

実行結果

012
None

仕組みの解説

s + s」という連結文字列の中には、s のあらゆる回転が必ず現れます。find メソッドに開始位置 1 と終了位置 -1 を指定することで、先頭にそのまま現れる一致や、末尾に張り付くだけの一致を除外しています。

もしインデックス i(1 以上)で s が見つかったなら、それは「s の先頭 i 文字が繰り返し単位である」ことを意味します。したがって s[:i] を返せば周期が得られます。見つからなければ -1 が返されるため、None を返して「繰り返しなし」を示します。

この手法は追加のライブラリ不要で、正規表現などを使うよりも簡潔に書けるのが魅力です。文字列の周期性チェックが必要になった際に、ぜひ活用してみてください。

  1. Pythonの文字列は不変(イミュータブル)!同じ文字列でもid()が変わる仕組みを解説

    Pythonにおいて、文字列(str型)は不変(イミュータブル)なオブジェクトです。つまり、一度作成された文字列は後から変更できません。また、Pythonでは同じ内容の文字列を作成して別々の変数に代入した場合、両方の変数が同じ文字列オブジェクト(同じメモリ領域)を参照するように最適化されることがあります。実際に確認してみましょう。同じ文字列は同じid()を持つケース>>> a = hi >>> b = hi >>> id(a) 43706848L >>> id(b) 43706848Lこのように、変数aと変数bはまったく同

  2. Pythonで複数の区切り文字を使って文字列を分割する方法

    re.split()メソッドによる複数区切り文字での分割Pythonでは、標準ライブラリのreモジュールが提供するre.split(区切り文字, 文字列)メソッドを使うことで、複数の区切り文字を指定して文字列を簡単に分割できます。このメソッドには、区切り文字を表す正規表現パターンと、分割したい文字列を渡します。基本的な使い方次の例では、セミコロン(;)、カンマ(,)、アスタリスク(*)、改行(\n)という4種類の区切り文字を、1つの正規表現でまとめて処理しています。a = Beautiful, is; better*than\nugly import re print(re.split(; |