10

Javaと正規表現を使用して繰り返しシーケンスを探すランダムな文字列を解析します。

文字列について考えてみましょう。

aaabbaaacccbb

上記の文字列内のすべての一致を検索する正規表現を見つけたいと思います。

aaabbaaacccbb
^^^  ^^^

aaabbaaacccbb
   ^^      ^^

文字列の文字の繰り返しシーケンスをチェックし、グループ1=aaaおよびグループ2=bbのようにそれらの繰り返し文字のグループを返す正規表現は何ですか。また、サンプル文字列を使用しましたが、繰り返し文字はすべて有効であることに注意してください:RonRonJoeJoe ... ... ,, ,, ... ,,

4

5 に答える 5

9

これはそれを行います:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(String[] args) {
        String s = "aaabbaaacccbb";
        find(s);
        String s1 = "RonRonRonJoeJoe .... ,,,,";
        find(s1);
        System.err.println("---");
        String s2 = "RonBobRonJoe";
        find(s2);
    }

    private static void find(String s) {
        Matcher m = Pattern.compile("(.+)\\1+").matcher(s);
        while (m.find()) {
            System.err.println(m.group());
        }
    }
}

出力:

aaa
bb
aaa
ccc
bb
RonRonRon
JoeJoe
....
,,,,
---
于 2012-04-23T20:34:19.847 に答える
3

以下は、すべての要件に対して機能するはずです。実際には、ここでのいくつかの回答の組み合わせであり、文字列内の他の場所で繰り返されるすべての部分文字列が出力されます。

少なくとも 2 文字の部分文字列のみを返すように設定しましたが、正規表現の「{2,}」を「+」に変更することで、簡単に 1 文字に変更できます。

public static void main(String[] args)
{
  String s = "RonSamJoeJoeSamRon";
  Matcher m = Pattern.compile("(\\S{2,})(?=.*?\\1)").matcher(s);
  while (m.find())
  {
    for (int i = 1; i <= m.groupCount(); i++)
    {
      System.out.println(m.group(i));
    }
  }
}

出力:
ロン
・サム・
ジョー

于 2012-04-23T21:16:30.910 に答える
2

このpositive lookahead ベースの正規表現を使用できます。

((\\w)\\2+)(?=.*\\1)

コード:

String elem = "aaabbaaacccbb";
String regex = "((\\w)\\2+)(?=.*\\1)";
Pattern p = Pattern.compile(regex);
Matcher matcher = p.matcher(elem);
for (int i=1; matcher.find(); i++)
System.out.println("Group # " + i + " got: " + matcher.group(1));

出力:

Group # 1 got: aaa
Group # 2 got: bb
于 2012-04-23T20:32:39.957 に答える
0

サブシーケンスも提供しますが、これは機能しているようです。

(公平を期すために、これはGuillameのコードから構築されました)

public static void main(final String[] args) {
    // final String s = "RonRonJoeJoe";
    // final String s = "RonBobRonJoe";
    final String s = "aaabbaaacccbb";

    final Pattern p = Pattern.compile("(.+).*\\1");

    final Matcher m = p.matcher(s);
    int start = 0;
    while (m.find(start)) {
        System.out.println(m.group(1));
        start = m.toMatchResult().end(1);
    }
}
于 2012-04-23T20:56:44.683 に答える
0

オーバーラップは無視できます。

// overlapped 1 or more chars
(?=(\w{1,}).*\1)
// overlapped 2 or more chars
(?=(\w{2,}).*\1)
// overlapped 3 or more chars, etc ..
(?=(\w{3,}).*\1)

または、(重複していない)を消費することもできます..

// 1 or more chars
(?=(\w{1,}).*\1) \1
// 2 or more chars
(?=(\w{2,}).*\1) \1
// 3 or more chars, etc ..
(?=(\w{3,}).*\1) \1
于 2012-04-23T23:02:09.447 に答える