2016-07-12 5 views
4

期間pを検出するための正規表現は、そのw[i]=w[i+p] 、この式の両辺が定義されているときはいつでも任意の正の整数pです。 per(w)は、wの最小期間のサイズ を示します。文字列wは periodic iff です。周期ストリングストリング<code>w</code>の

したがって、非公式に周期的な文字列は、少なくとも2回繰り返したプレフィックスから構成された単なる文字列です。唯一の問題は、文字列の最後に接頭辞の完全なコピーを必要としないということです。

たとえば、文字列x = abcabを考えてください。 per(abcab) = 3x[1] = x[1+3] = a,x[2]=x[2+3] = bとし、それより小さい期間はありません。したがって、文字列abcabは周期的ではありません。ただし、文字列ababaは、周期的で、per(ababa) = 2です。

さらに多くの例として、abcabca,ababababaおよびabcabcabcも周期的です。

文字列が周期的であるかどうかを判断する正規表現はありますか?

私は本当に正規表現の味が気にしませんが、違いがある場合は、Python reに対応しています。

+0

どの言語を使用していますか? –

+0

@Kilannyこれは一般的な正規表現の質問ですが、それが違いを生むならば、Pythonがサポートしているものはどれも。 – eleanora

+0

@ClasG下のhorcruxの答えはどうですか? – eleanora

答えて

5

はこれもabcabcaababababa一致する後方参照

\b(\w*)(\w+\1)\2+\b 

です。

逆参照(この場合は必要)のメカニズムは、に属する式を正規の文法にしないことに注意してください。

+0

これはとてもいいですね!私はちょうどそれで遊んでいます。 – eleanora

+0

空の文字列も定期的に考えると、右の式は '\ b(\ w *)(\ w * \ 1)\ 2+ \ b' – horcrux

+1

です。私のものよりも短いですが、ちょっと理解しにくいかもしれません。あなたは '\ b ... \ b'の代わりに'^... $ 'を使って、文字列全体が確実に定期的であるようにしてください。 –

4

Regexバックリファレンスを使用できます。

たとえば、(.+)\1+。このパターンは、少なくとも1つの文字.+で構成されたグループ()と一致します。このグループ\1(バックリファレンス)は、一致するために少なくとも1回繰り返す必要があります。

文字列ababaが一致し、第1グループとしてabが見つかりました。

文字列abcabは一致しません。 ^(.+)\1+

後で、少なくとも2回繰り返しプレフィックスをしたい場合は、あなたがにパターンを変更することができます

を編集します。問題は、文字列の最後を接頭辞の部分文字列に一致させることはできないと思います。したがって、繰り返しパターンで始まる文字列は一致しますが、文字列の終わりは無視されます。

をしても、後で@tobias_k答えからインスピレーションを受け

を編集し、ここで私はそれを^((.+)(?:.*))\1+\2?$を行うだろう方法です。これは、少なくとも2回繰り返される接頭辞(見つけられる最も長い接頭辞を探します)を持つ文字列を探し、接頭辞は接頭辞の先頭部分でなければなりません。

一致する最初のキャプチャグループは、繰り返しているプレフィックスになります。

https://regex101.com/r/jQ3yY1/2

あなたが繰り返される最短の接頭辞をしたい場合は、このパターン^((.+?)(?:.*?))\1+\2?$を使用することができます。あなたが必要なもの

+0

'abcabca'はどうですか? – eleanora

+0

これはabcと一致します。あなたはここで遊ぶことができます:https://regex101.com/r/jQ3yY1/1 – Andrew

+0

ありがとうございますが、私は何かが間違っていると思います。私がabcabcabを試してみたら、 "abcabc"とマッチするはずの "abcabc"とマッチします(これがすべてです)。 – eleanora

4

^(.+)(.*)(\1\2)+\1?$のような正規表現を使用できます。スタートから文字列

  • (.+)の終わりに

    • ^...$常に繰り返される期間の一部(ababaで例えばa)終わりを除いて繰り返され、期間の
    • (.*)オプションパーツ(ababaで例えばb
    • (\1\2)+全期間の1回以上の繰り返し
    • \1?オプションのfinal Pythonで期間

    の最初の部分の繰り返し:これはまた、定期的に考慮することができるものの、空の文字列""を、一致しないことが

    >>> p = r"^(.+)(.*)(\1\2)+\1?$" 
    >>> re.match(p, "abcab") 
    None 
    >>> re.match(p, "abcabca") 
    <_sre.SRE_Match at 0x7f5fde6e51f8> 
    

    注意。空の文字列を一致させる必要がある場合は、別々に扱う必要があります。単に正規表現の最後に|^$を追加するだけです。

  • +0

    "繰り返されているが非常にそうではないグループ"。 「非常に」とはどういう意味ですか? – eleanora

    +0

    @eleanoraそれは私がタイプミスをしたことを意味します。一定。 –