Найти все вхождения подстроки в строку в Java

Я пытаюсь найти все вхождения подстроки в строку в Java.

например: поиск "ababsdfasdfhelloasdf" для "asdf" вернется [8,17], так как есть 2 "asdf", один в позиции 8 и один в 17. Поиск " aaaaaa "для" aa "вернет [0,1,2,3,4], потому что есть" aa " в позициях 0,1,2,3 и 4.

Я попытался это:

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())]

где "слово" - это слово, которое я ищу, и " А " - это строка, которую я ищу.

Как я могу достичь этого в Java?

2 ответов


вы можете использовать захват внутри позитивного взгляда вперед, чтобы получить все перекрывающиеся матчи и использовать 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 demo


использование регулярного выражения, безусловно, является слишком тяжелым решением для поиска подстрок, и это особенно будет проблемой, если ваша подстрока содержит специальные символы регулярного выражения, такие как .. Вот решение, адаптированное ответ:

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;
    }
}