Есть ли replaceLast()
в Java? Я видел, что есть replaceFirst()
.
EDIT: Если в SDK нет, что было бы хорошей реализацией?
Есть ли replaceLast()
в Java? Я видел, что есть replaceFirst()
.
EDIT: Если в SDK нет, что было бы хорошей реализацией?
Можно (конечно) сделать с помощью регулярного выражения:
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", "--"));
}
}
хотя бит-цикл-голодный с перспективами, но это будет проблемой только при работе с очень большими строками (и во многих случаях поиска регулярных выражений).
Краткое объяснение (в случае регулярного выражения 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
}
используйте replaceAll и добавьте знак доллара сразу после вашего шаблона:
replaceAll("pattern$", replacement);
Смотрите сами: 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();
}
Вы можете комбинировать StringUtils.reverse()
с String.replaceFirst()
Использовать StringUtils из apache:
org.apache.commons.lang.StringUtils.chomp(value, ignoreChar);
Нет.
Вы можете сделать reverse
/replaceFirst
/reverse
, но это немного дорого.
Если проверенная строка такова, что
myString.endsWith(substringToReplace) == true
вы также можете сделать
myString=myString.replaceFirst("(.*)"+myEnd+"$","$1"+replacement)
он медленный, но работает: 3
import org.apache.commons.lang.StringUtils;
public static String replaceLast(String str, String oldValue, String newValue) {
str = StringUtils.reverse(str);
str = str.replaceFirst(StringUtils.reverse(oldValue), StringUtils.reverse(newValue));
str = StringUtils.reverse(str);
return str;
}
разделите стог сена вашей иглой с помощью регулярного выражения lookahead и замените последний элемент массива, затем соедините их вместе: D
String haystack = "haystack haystack haystack";
String lookFor = "hay";
String replaceWith = "wood";
String[] matches = haystack.split("(?=" + lookFor + ")");
matches[matches.length - 1] = matches[matches.length - 1].replace(lookFor, replaceWith);
String brandNew = StringUtils.join(matches);
Я также столкнулся с такой проблемой, но я использую этот метод:
public static String replaceLast2(String text,String regex,String replacement){
int i = text.length();
int j = regex.length();
if(i<j){
return text;
}
while (i>j&&!(text.substring(i-j, i).equals(regex))) {
i--;
}
if(i<=j&&!(text.substring(i-j, i).equals(regex))){
return text;
}
StringBuilder sb = new StringBuilder();
sb.append(text.substring(0, i-j));
sb.append(replacement);
sb.append(text.substring(i));
return sb.toString();
}
Это действительно работает. Просто добавьте свою строку, где вы хотите заменить строку в s, а вместо "he" поместите подстроку u, которую хотите заменить, а вместо "mt" поместите нужную строку в новую строку.
import java.util.Scanner;
public class FindSubStr
{
public static void main(String str[])
{
Scanner on=new Scanner(System.in);
String s=on.nextLine().toLowerCase();
String st1=s.substring(0, s.lastIndexOf("he"));
String st2=s.substring(s.lastIndexOf("he"));
String n=st2.replace("he","mt");
System.out.println(st1+n);
}
}