java replaceLast()

Car*_*nco 54 java string

replaceLast()Java吗?我看到了replaceFirst().

编辑:如果SDK中没有,那么什么是好的实现?

Bar*_*ers 52

它(当然)可以用正则表达式完成:

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", "--"));
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然有点cpu-cycle-hungry with the ahead-ahead,但这只会在处理非常大的字符串时出现问题(并且正在搜索许多正则表达式).

一个简短的解释(在正则表达式的情况下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
Run Code Online (Sandbox Code Playgroud)

编辑

抱歉醒了一个旧帖子.但这仅适用于非重叠的实例.例如,.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"));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 抱歉醒了一个旧帖子.但这仅适用于非重叠的实例.例如`.replaceLast("aaabbb","bb","xx");`返回`"aaaxxb"`,而不是`"aabxx"` (3认同)

Bal*_*usC 32

如果你不需要正则表达式,这里有一个子串替代方案.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

测试用例:

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
}
Run Code Online (Sandbox Code Playgroud)

  • @Thomas,它还说"如果你不需要正则表达式......"在答案的顶部:) (7认同)

小智 15

使用replaceAll并在您的模式后面添加一个美元符号:

replaceAll("pattern$", replacement);
Run Code Online (Sandbox Code Playgroud)

  • 这仅在最后一个实例是最后一个值时有效.即,s = s.replaceAll(".1 $",".2"); hi.1将是hi.2,但如果我做了喜.12它仍然是hi.12"hi.1" - >"hi.2"(好)"hi.12" - >"hi.12" (差)"hi.11" - >"hi..2"(差)"hi.111" - >"hi.1.2"(差)"hi.1111" - >"hi.11.2"(差)The对我来说好事是,我需要它作为最后一个实例,它将是最后一个值:).只是想为那些可能找到这个答案的人注意这一点. (5认同)

Mih*_*ria 8

你可以结合StringUtils.reverse()使用String.replaceFirst()

  • abcdefg将是gfedcba,你必须修改你的正则表达式来取代"反向"目标. (8认同)

Joa*_*uer 7

你自己看: String

或者你的问题实际上是"我如何实现replaceLast()?"

让我尝试一个实现(这应该表现得很像replaceFirst(),所以它应该支持替换String中的正则表达式和反向引用):

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();
}
Run Code Online (Sandbox Code Playgroud)


小智 5

从Apache使用StringUtils:

org.apache.commons.lang.StringUtils.chomp(value, ignoreChar);
Run Code Online (Sandbox Code Playgroud)

  • 不推荐使用StringUtils.removeEnd,它可以正常工作。 (3认同)