Подтвердить что ты не робот

Java replaceLast()

Есть ли replaceLast() в Java? Я видел, что есть replaceFirst().

EDIT: Если в SDK нет, что было бы хорошей реализацией?

4b9b3361

Ответ 1

Можно (конечно) сделать с помощью регулярного выражения:

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

Ответ 2

Если вам не нужно регулярное выражение, используйте альтернативу подстроки.

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
}

Ответ 3

используйте replaceAll и добавьте знак доллара сразу после вашего шаблона:

replaceAll("pattern$", replacement);

Ответ 4

Смотрите сами: 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();
}

Ответ 5

Вы можете комбинировать StringUtils.reverse() с String.replaceFirst()

Ответ 6

Использовать StringUtils из apache:

org.apache.commons.lang.StringUtils.chomp(value, ignoreChar);

Ответ 7

Нет.

Вы можете сделать reverse/replaceFirst/reverse, но это немного дорого.

Ответ 8

Если проверенная строка такова, что

myString.endsWith(substringToReplace) == true

вы также можете сделать

myString=myString.replaceFirst("(.*)"+myEnd+"$","$1"+replacement) 

Ответ 9

он медленный, но работает: 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;
}

Ответ 10

разделите стог сена вашей иглой с помощью регулярного выражения 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);

Ответ 11

Я также столкнулся с такой проблемой, но я использую этот метод:

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

Ответ 12

Это действительно работает. Просто добавьте свою строку, где вы хотите заменить строку в 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);
 }

}