文字パターンが繰り返される可能性のある文字列があります。
'xyzzyxxyzzyxxyzzyx'
このような文字列を最小の繰り返しパターンに置き換える正規表現を作成する必要があります。
'xyzzyxxyzzyxxyzzyx' becomes 'xyzzyx',
'abcbaccbaabcbaccbaabcbaccba' becomes 'abcbaccba'
以下を使用してください。
> re.sub(r'(.+?)\1+', r'\1', 'xyzzyxxyzzyxxyzzyx')
'xyzzyx'
> re.sub(r'(.+?)\1+', r'\1', 'abcbaccbaabcbaccbaabcbaccba')
'abcbaccba'
> re.sub(r'(.+?)\1+', r'\1', 'iiiiiiiiiiiiiiiiii')
'i'
基本的に、それ自体を繰り返すパターンと一致(.+?)\1+
し、最初のグループでキャプチャされた繰り返しパターン以外のすべてを削除します\1
。また、ここで気が進まない修飾子を使用すると、つまり、+?
正規表現のバックトラックが非常に多くなることに注意してください。
デモ。
最小の繰り返しパターンが必要なため、次のようなものが機能するはずです。
re.sub(r'^(.+?)\1+$', r'\1', input_string)
^
およびアンカーは$
、文字列の途中で一致しないようにし、.+?
代わりに just.+
を使用することで、最短のパターンを取得します ( のような文字列を使用して結果を比較します'aaaaaaaaaa'
)。
この正規表現パターンを試して、最初のグループをキャプチャします。
^(.+?)\1+$
^
文字列/行の先頭のアンカー.
改行以外のすべての文字+
少なくとも1回の出現を示す数量詞?
+
貪欲ではなく怠惰になるため、最短のパターンが得られます()
キャプチャグループ\1+
パターンが少なくとも1回繰り返される必要があることを示す数量詞を使用した後方参照$
文字列/行の終わりのアンカーここでテストしてください:Rubular
上記のソリューションは、パフォーマンスに影響を与える多くのバックトラックを実行します。これらの文字列で許可されていない文字がわかっている場合は、バックトラックを排除する否定文字セットを使用できます。たとえば、空白が許可されていない場合は、
^([^\s]+)\1+$