Java Заменить несколько подстрок (на основе индексов)

У меня есть строка вроде

'John is a student. He is also a researcher. He is also a human.'

У меня есть начальный и конечный индексы John и первый He. Есть ли способ заменить эти подстроки одновременно на x. Обратите внимание, что мне не следует заменять второй He, потому что у меня есть индексы только для первого He.

Очевидно, мы можем перебирать строку, копировать всякий раз, когда указатель не находится в окне подстроки, и вместо этого помещать x. Но есть ли способ лучше, чем этот?

Также обратите внимание, что индексы не перекрываются.


person Raghuram Vadapalli    schedule 19.05.2016    source источник
comment
Что вы имеете в виду одновременно?   -  person Andy Turner    schedule 19.05.2016
comment
Я имею в виду, если вы сначала замените John. Тогда индексы He больше не представляют He. Итак, одновременно.   -  person Raghuram Vadapalli    schedule 19.05.2016
comment
Пожалуйста, покажите, что вы пробовали до сих пор. Ваш вопрос непонятен.   -  person Andy Turner    schedule 19.05.2016
comment
@AndyTurner Я получил ответ. См. Принятый ответ.   -  person Raghuram Vadapalli    schedule 19.05.2016


Ответы (4)


Замена с торца - лучшее решение.

public class NE {
     public Integer startIndex;
     public Integer endIndex;
}

public class CustomComparator implements Comparator<NE> {
    public int compare(NE n1, NE n2) {
        return n1.startIndex.compareTo(n2.startIndex);
    }
}

ArrayList<NE> NEList = getIndexes();
Collections.sort(NEList, ner.new CustomComparator());

String finalString = 'John is a student. He is also a researcher. He is also a human.';
for(int i=NEList.size()-1;i>=0;i--){
    NE ne = ner.new NE();
    ne = NEList.get(i);
    finalString = new StringBuilder(finalString).replace(ne.startIndex, ne.endIndex, 'x').toString();
}
System.out.println(finalString);

Кредиты: @AndyTurner

person Raghuram Vadapalli    schedule 20.05.2016

Я не знаю, как изменить оба с помощью индекса. Но послушайте, вы, вероятно, сначала нашли индекс, выполнив поиск подстрок John и He. Так что вы можете пропустить это и использовать статический метод Strings replaceAll.

String test = "John is a student. He is also a researcher.";
System.out.println(test.replaceAll("(John)|(He)", "x"));

Фактически вы проверяете, находится ли (John)|(He) («Джон» или «Он») в строковом тесте. Если да, то они заменяются на "x".

replaceAll возвращает ссылку на новый объект String следующего вида:

x студент. x также является исследователем.

person Robert van der Spek    schedule 19.05.2016
comment
Я никогда не говорил, что искал и получил эти индексы. Какой-то API дал мне эти индексы. - person Raghuram Vadapalli; 19.05.2016
comment
В этом случае мне очень любопытно, как вы получили эти индексы. Вы, должно быть, дали какое-то задание. Итак, что вы сделали, чтобы получить эти индексы? - person Robert van der Spek; 19.05.2016
comment
Предположим, у меня есть функция ArrayList giveIndexes(String s), которая творит черную магию и дает мне эти индексы. :П - person Raghuram Vadapalli; 19.05.2016

попробуй это :

String s="John is a student. He is also a researcher.";

        int beginIndex=s.indexOf("He");
        s=s.substring(0, beginIndex)+"x"+s.substring(beginIndex+2,s.length());

Вывод: Джон - студент. x тоже исследователь.

person Amar Bessalah    schedule 19.05.2016
comment
Пожалуйста, прочтите внимательно вопрос. Если получаемые мной индексы относятся ко второму He, то первый He не подлежит замене. - person Raghuram Vadapalli; 19.05.2016
comment
он не будет заменен; мы заменим только тот, у которого начальный индекс - beginIndex, в моем случае я использовал beginIndex = s.indexOf (); но вы можете использовать нужный beginIndex. - person Amar Bessalah; 19.05.2016
comment
Предлагаю внимательно прочитать вопрос. Я не ищу He. Какой-то черный ящик дает мне начальный и конечный индексы John и He. - person Raghuram Vadapalli; 19.05.2016

Вы можете использовать заполнитель с той же длиной слова для замены. Затем замените заполнители на x и получите результат.

 String s = "John is a student. He is also a researcher.";
 int firstStart = 0,firstEnd =4,secondStart=19,secondEnd=21;

 String firstPlaceholder = String.format("%"+(firstEnd - firstStart )+"s", " ").replaceAll(" ", "x");
 String secondPlaceholder = String.format("%"+(secondEnd -secondStart)+"s", " ").replaceAll(" ", "x");

 String result = new StringBuilder(s).replace(firstStart, firstEnd, firstPlaceholder)
                                        .replace(secondStart, secondEnd, secondPlaceholder)
                                        .toString().replaceAll("x[x]+", "x");
 System.out.println( result);

выход:

x is a student. x is also a researcher.

надеюсь, это поможет.

person Mario Cairone    schedule 19.05.2016
comment
Большой!! Это то, что я ищу. Спасибо. : D. Хотя небольшое изменение. Первый "xxxx" не должен быть жестко запрограммирован. Можете ли вы изменить ответ так, чтобы "xxxx" была строкой x длиной John. - person Raghuram Vadapalli; 19.05.2016
comment
Из вопроса не ясно, что следует заменить John на xxxx - похоже, его следует заменить на x. - person Andy Turner; 19.05.2016
comment
@AndyTurner, да. Я хочу заменить его на x. Пожалуйста, ответьте, сможете ли вы этого добиться. Я буду рад. - person Raghuram Vadapalli; 19.05.2016
comment
@ Achilles-96 нет, это не ясно: я хочу заменить каждый символ «Джон» на «x», описывающий это. Просто сказать, что я хочу заменить John на x, означает заменить J и удалить ohn. - person Andy Turner; 19.05.2016
comment
@AndyTurner, я не хочу заменять каждый символ на x, поэтому я попросил редактировать ответ. Я хочу, чтобы все слово было заменено на x. @Mario Cairone, удалите вторую часть ответа. Как я уже сказал, я не хочу заменять каждого персонажа. - person Raghuram Vadapalli; 19.05.2016
comment
Как я уже сказал, пожалуйста, не программируйте жестко. Вместо "x$$$" введите что-то вроде "x" + f(4-0), где f (n) возвращает строку из $ длины n-1. - person Raghuram Vadapalli; 19.05.2016
comment
Я сделал этот комментарий до того, как мне передали последнее изменение. Принято. :) - person Raghuram Vadapalli; 19.05.2016
comment
Что, если строка John is a xxxxxx. He is also a xxxxxxxx. - последний replaceAll уничтожит полностью несвязанные биты строки. - person Andy Turner; 19.05.2016
comment
Правильно указано. $ - лучший вариант. Любой случайный символ, который обычно не используется, - лучший вариант. Спасибо - person Raghuram Vadapalli; 19.05.2016
comment
Тогда ... что, если строка John is a x$$$$$. He is also a x$$$$$$$.? - person Andy Turner; 19.05.2016
comment
Вот почему я сказал любой иероглиф, который обычно не используется. Уфф. - person Raghuram Vadapalli; 19.05.2016
comment
Однако в этом нет необходимости, если вы просто замените в обратном порядке: new StringBuilder(s).replace(secondStart, secondEnd, "x").replace(firstStart, secondStart, "x").toString();. - person Andy Turner; 19.05.2016
comment
Позвольте нам продолжить это обсуждение в чате. - person Raghuram Vadapalli; 19.05.2016