ВАЖНО: Как было отмечено Kip в комментариях, этот класс имеет бесконечную ошибку петли, если соответствующий регулярное выражение соответствует на строку замены. Я оставлю это упражнением для читателей, чтобы исправить его, если это необходимо.
Я не знаю ничего подобного, что встроено в Java. Вы можете свернуть свой собственный без особых трудностей, с помощью класса Сличитель:
import java.util.regex.*;
public class CallbackMatcher
{
public static interface Callback
{
public String foundMatch(MatchResult matchResult);
}
private final Pattern pattern;
public CallbackMatcher(String regex)
{
this.pattern = Pattern.compile(regex);
}
public String replaceMatches(String string, Callback callback)
{
final Matcher matcher = this.pattern.matcher(string);
while(matcher.find())
{
final MatchResult matchResult = matcher.toMatchResult();
final String replacement = callback.foundMatch(matchResult);
string = string.substring(0, matchResult.start()) +
replacement + string.substring(matchResult.end());
matcher.reset(string);
}
}
}
Тогда звоните:
final CallbackMatcher.Callback callback = new CallbackMatcher.Callback() {
public String foundMatch(MatchResult matchResult)
{
return "<img src=\"thumbs/" + matchResults.group(1) + "\"/>";
}
};
final CallbackMatcher callbackMatcher = new CallbackMatcher("/\[thumb(\d+)\]/");
callbackMatcher.replaceMatches(articleText, callback);
Обратите внимание, что вы можете получить всю найденную строку с помощью вызова matchResults.group()
или matchResults.group(0)
, так что это не необходимо передать обратный вызов текущему состоянию строки.
EDIT: Это больше похоже на точную функциональность функции PHP.
Вот оригинал, так как просящие понравилась:
public class CallbackMatcher
{
public static interface Callback
{
public void foundMatch(MatchResult matchResult);
}
private final Pattern pattern;
public CallbackMatcher(String regex)
{
this.pattern = Pattern.compile(regex);
}
public String findMatches(String string, Callback callback)
{
final Matcher matcher = this.pattern.matcher(string);
while(matcher.find())
{
callback.foundMatch(matcher.toMatchResult());
}
}
}
Для этого конкретного случая использования, это может быть лучше просто очереди каждого матча в обратном вызове, то после запуска через них в обратном направлении. Это предотвратит необходимость переназначения индексов при изменении строки.
Я на самом деле нравится ваш первоначальный ответ лучше с очередями возвращенную строку и индексы. Затем применяя их в обратном порядке. Этот способ проще, но, похоже, делает больше работы, требуя повторной проверки всей строки для каждого совпадения. Спасибо за предложение! – Mike
Я добавил исходное предложение назад. Ожидаемый размер ввода будет иметь значение, будет ли более эффективным повторное сканирование или очередность, а затем замена. Я полагаю, что также можно было бы заменить метод замещения вместе с заменой строки ... – jdmichal
Errr ... Misspoke. Очевидно, что очередность всегда более эффективна в отношении времени процессора. Разница в том, будет ли это достаточно большой проблемой, о которой нужно беспокоиться. – jdmichal