Это можно (конечно) сделать с помощью регулярного выражения:
public class Test {
public static String replaceLast(String text, String regex, String replacement) {
return text.replaceFirst("(?s)"+regex+"(?!.*?"+regex+")", replacement);
}
public static void main(String[] args) {
System.out.println(replaceLast("foo AB bar AB done", "AB", "--"));
}
}
, хотя немного голодных циклов процессора с помощью look впереди, но это будет проблемой только при работе с очень большими строками (и во многих случаях поиска регулярного выражения).
Краткое объяснение (в случае регулярного выражения AB
):
(?s) # enable dot-all option
A # match the character 'A'
B # match the character 'B'
(?! # start negative look ahead
.*? # match any character and repeat it zero or more times, reluctantly
A # match the character 'A'
B # match the character 'B'
) # end negative look ahead
Извините, что разбудил старый пост. Но это только для неперекрывающихся экземпляров. Например,
.replaceLast ("aaabbb", "bb", "xx");
возвращает"aaaxxb"
, а не"aaabxx"
Правда, это можно было исправить следующим образом:
public class Test {
public static String replaceLast(String text, String regex, String replacement) {
return text.replaceFirst("(?s)(.*)" + regex, "$1" + replacement);
}
public static void main(String[] args) {
System.out.println(replaceLast("aaabbb", "bb", "xx"));
}
}
Если вам не нужно регулярное выражение, вот альтернатива подстроке.
public static String replaceLast(String string, String toReplace, String replacement) {
int pos = string.lastIndexOf(toReplace);
if (pos > -1) {
return string.substring(0, pos)
+ replacement
+ string.substring(pos + toReplace.length(), string.length());
} else {
return string;
}
}
Testcase:
public static void main(String[] args) throws Exception {
System.out.println(replaceLast("foobarfoobar", "foo", "bar")); // foobarbarbar
System.out.println(replaceLast("foobarbarbar", "foo", "bar")); // barbarbarbar
System.out.println(replaceLast("foobarfoobar", "faa", "bar")); // foobarfoobar
}
Вы можете объединить StringUtils.reverse ()
с String.replaceFirst ()
В нем говорится, что используется глобальная версия, а не объявленная в локальной области. Так что если кто-то объявил atof
в вашем классе, это обязательно будет использовать глобальный.
Посмотрите на Википедию на эту тему :
#include <iostream>
using namespace std;
int n = 12; // A global variable
int main() {
int n = 13; // A local variable
cout << ::n << endl; // Print the global variable: 12
cout << n << endl; // Print the local variable: 13
}
-121--1409669- В целом они эквивалентны. Но в контексте использования делегата для типа события соглашение должно использовать EventHandler (где T наследует EventArgs):
public event EventHandler<EmployeeEventArgs> Left;
public void Leave()
{
OnLeft(this.ID);
}
protected virtual void OnLeft(int id)
{
if (Left != null) {
Left(new EmployeeEventArgs(id));
}
}
-121--988039- No.
Можно выполнить обратный
/ repleyFirst
/ обратный
, но это немного дорого.
Смотрите сами: String
Или ваш вопрос на самом деле "Как мне реализовать replaceLast()
?"
Позвольте мне попробовать реализовать (это должно вести себя почти как replaceFirst()
, поэтому оно должно поддерживать регексы и обратные ссылки в заменяющей строке):
public static String replaceLast(String input, String regex, String replacement) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (!matcher.find()) {
return input;
}
int lastMatchStart=0;
do {
lastMatchStart=matcher.start();
} while (matcher.find());
matcher.find(lastMatchStart);
StringBuffer sb = new StringBuffer(input.length());
matcher.appendReplacement(sb, replacement);
matcher.appendTail(sb);
return sb.toString();
}