web-dev-qa-db-ja.com

Java)内の文字列内の部分文字列のすべての出現を検索します

Javaの文字列内の部分文字列のすべての出現箇所を見つけようとしています。

たとえば、「ababsdfasdfhelloasdf」で「asdf」を検索すると[8,17]が返されます。これは、「asdf」が2つあり、1つは位置8に、もう1つは17にあるためです。「aaaaaa」で「aa」を検索すると[0、 1,2,3,4]位置0、1、2、3、および4に「aa」があるため。

私はこれを試しました:

public List<Integer> findSubstrings(String inwords, String inword) {
    String copyOfWords = inwords;
    List<Integer> indicesOfWord = new ArrayList<Integer>();
    int currentStartIndex = niwords.indexOf(inword);
    int indexat = 0;
    System.out.println(currentStartIndex);
    while (cthing1 > 0) {
        indicesOfWord.add(currentStartIndex+indexat);
        System.out.println(currentStartIndex);
        System.out.println(indicesOfWord);
        indexat += cthing1;
        copyOfWords = copyOfWords.substring(cthing1);
        System.out.println(copyOfWords);
        cthing1 = copyOfWords.indexOf(inword);
    }

この問題は、次のようにPythonで解決できます。

indices = [m.start() for m in re.finditer(Word, a.lower())]

ここで、「Word」は私が探している単語であり、「a」は私が検索している文字列です。

Javaでこれを実現するにはどうすればよいですか?

10
Kevin

ポジティブルックアヘッド内のキャプチャを使用して、重複するすべての一致を取得し、Matcher#startを使用してキャプチャされた部分文字列のインデックスを取得できます。

正規表現 については、次のようになります。

(?=(aa))

Javaコード:

String s = "aaaaaa";
Matcher m = Pattern.compile("(?=(aa))").matcher(s);
List<Integer> pos = new ArrayList<Integer>();
while (m.find())
{
    pos.add(m.start());
}
System.out.println(pos);

結果:

[0, 1, 2, 3, 4]

IDEONEデモ を参照してください

10

正規表現を使用することは、部分文字列を見つけるための非常に重い解決策であることは間違いありません。部分文字列に.などの特殊な正規表現文字が含まれている場合は特に問題になります。これが この答え から適応した解決策です:

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
List<Integer> result = new ArrayList<Integer>();

while(lastIndex != -1) {

    lastIndex = str.indexOf(findStr,lastIndex);

    if(lastIndex != -1){
        result.add(lastIndex);
        lastIndex += 1;
    }
}
1
Alex Hall