在 Java 中修剪字符串的可能前缀

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21545933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:18:22  来源:igfitidea点击:

Trim a possible prefix of a string in Java

javaregexstring

提问by barak manos

I have String str, from which I want to extract the sub-string excluding a possible prefix "abc".

我有String str,我想从中提取不包括可能的前缀的子字符串"abc"

The first solution that comes to mind is:

想到的第一个解决方案是:

if (str.startsWith("abc"))
    return str.substring("abc".length());
return str;

My questions are:

我的问题是:

  1. Is there a "cleaner" way to do it using splitand a regular expression for an "abc"prefix?

  2. If yes, is it less efficient than the method above (because it searches "throughout" the string)?

  3. If yes, is there any better way of doing it (where "better way" = clean and efficient solution)?

  1. 是否有一种“更干净”的方法来使用前缀split和正则表达式?"abc"

  2. 如果是,它是否比上面的方法效率低(因为它搜索“整个”字符串)?

  3. 如果是,是否有更好的方法(“更好的方法”= 干净有效的解决方案)?

Please note that the "abc"prefix may appear elsewhere in the string, and should not be removed.

请注意,"abc"前缀可能出现在字符串的其他地方,不应删除。

Thanks

谢谢

回答by anubhava

Shorter than above code will be this line:

比上面的代码更短的是这一行:

return str.replaceFirst("^abc", "");

But in terms of performance I guess there wont be any substantial difference between 2 codes. One uses regex and one doesn't use regex but does search and substring.

但就性能而言,我想 2 个代码之间不会有任何实质性差异。一种使用正则表达式,一种不使用正则表达式,但进行搜索和子字符串。

回答by Maroun

  1. Using String#splitcan do this, but it's not better solution. Actually it'll be vague and I wouldn't recommend using it for that purpose.
  2. Don't waste time about efficiency in this case, it's not significant, focus on logic and clarity. But note that working with regex is usually slower because it involves additional operations so you might want to keep startsWith.
  3. Your approach is fine, if you want to check if the String begins with "abc", String#startsWithwas designed for that.
  1. 使用String#split可以做到这一点,但这不是更好的解决方案。实际上它会很模糊,我不建议为此目的使用它。
  2. 在这种情况下不要浪费时间在效率上,这并不重要,专注于逻辑和清晰度。但请注意,使用正则表达式通常较慢,因为它涉及额外的操作,因此您可能希望保留startsWith.
  3. 你的方法很好,如果你想检查字符串是否以“abc”开头,String#startsWith是为此而设计的。


You can easily measure the time that takes a code to run. Here what you can do:

您可以轻松地测量运行代码所需的时间。你可以在这里做什么:

Create a big loop, inside it you can append the counter of it to some dummy String in order to simulate the Strings you want to check, then try to have startsWithonce, and replaceAllafter:

创建一个大循环,在其中您可以将它的计数器附加到一些虚拟字符串以模拟您要检查的字符串,然后尝试拥有startsWith一次,然后replaceAll

for(int i = 0;i<900000;i++) {
    StringBuilder sb = new StringBuilder("abc");
    sb.append(i);
    if(sb.toString().startsWith("abc")) { ... } 
}
long time = System.currentTimeMillis() - start;
System.out.println(time); //Prints ~130


for(int i = 0;i<900000;i++){
   StringBuilder sb = new StringBuilder("abc");
   sb.append(i);
   sb.toString().replaceAll("^abc", "");        
}
long time = System.currentTimeMillis() - start;
System.out.println(time);  //Prints ~730

回答by Evgeniy Dorofeev

Try this

尝试这个

str = str.replaceAll("^abc", "");

回答by gursahib.singh.sahni

As far as efficiency is concerned you may use StringBuilderwhere you have multiple operations on one string such as substring then, finding index, then substring etc etc.

就效率而言,您可以使用StringBuilder对一个字符串进行多项操作的地方,例如子字符串然后查找索引,然后是子字符串等。



Where cleanliness/efficiency is concerned, StringUtils (Apache Commons Lang)can be used.

在涉及清洁度/效率的情况下,StringUtils (Apache Commons Lang)可以使用。

Hope it helps.

希望能帮助到你。

回答by falsetru

Using String.replaceFirstwith ^abc(to match leading abc)

使用String.replaceFirstwith ^abc(匹配领先abc

"abcdef".replaceFirst("^abc", "")     // => "def"
"123456".replaceFirst("^abc", "")     // => "123456"
"123abc456".replaceFirst("^abc", "")  // => "123abc456"

回答by mseebach

A regex-free solution (I needed this because the string I'm removing is configurable and contains backslashes, which need escaping for literal use in a regex):

一个无正则表达式的解决方案(我需要这个,因为我要删除的字符串是可配置的并且包含反斜杠,需要转义以在正则表达式中使用字面量):

Apache Commons Lang StringUtils.removeStart(str, remove)will remove removefrom the start of strusing String.startsWithand String.substring.

Apache Commons LangStringUtils.removeStart(str, remove)将删除remove从开始str使用的String.startsWithString.substring

The source codeof the method is informative:

该方法的源代码信息丰富:

public static String removeStart(final String str, final String remove) {
    if (isEmpty(str) || isEmpty(remove)) {
        return str;
    }
    if (str.startsWith(remove)){
        return str.substring(remove.length());
    }
    return str;
}

回答by Sokolov

If you are concerned about performance you can improve str.replaceFirst("^abc", "")solution by using same pre-compiled prefix Patternfor matching multiple strings.

如果您担心性能,您可以str.replaceFirst("^abc", "")通过使用相同的预编译前缀Pattern来匹配多个字符串来改进解决方案。

final Pattern prefix = Pattern.compile("^abc"); // Could be static constant etc
for ... {
    final String result = prefix.matcher(str).replaceFirst("");
}

I guess the difference will be noticeable if you stripping the same prefix from a lot of strings.

我想如果你从很多字符串中去掉相同的前缀,差异会很明显。