修剪Java中字符串的可能前缀
我有修剪Java中字符串的可能前缀,java,regex,string,Java,Regex,String,我有字符串str,我想从中提取子字符串,不包括可能的前缀“abc” 首先想到的解决方案是: if (str.startsWith("abc")) return str.substring("abc".length()); return str; 我的问题是: if (str.startsWith("abc")) return str.substring("abc".length()); return str; 是否有一种“更干净”的方法可以使用split和“abc”前缀的正则
字符串str
,我想从中提取子字符串,不包括可能的前缀“abc”
首先想到的解决方案是:
if (str.startsWith("abc"))
return str.substring("abc".length());
return str;
我的问题是:
if (str.startsWith("abc"))
return str.substring("abc".length());
return str;
split
和“abc”
前缀的正则表达式来执行此操作“abc”
前缀可能出现在字符串的其他位置,不应删除
谢谢比上面短的代码将是这一行:
return str.replaceFirst("^abc", "");
但就性能而言,我想两种代码之间不会有任何实质性的差异。一个使用正则表达式,一个不使用正则表达式,但使用搜索和子字符串
startsWith
您可以轻松地测量代码运行所需的时间。以下是您可以做的: 创建一个大循环,在其中,您可以将其计数器附加到某个伪字符串,以模拟要检查的字符串,然后尝试使用
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(inti=0;i试试这个
str = str.replaceAll("^abc", "");
就效率而言,您可以使用StringBuilder
在一个字符串上执行多个操作,如子字符串、查找索引、子字符串等
就清洁度/效率而言,可以使用StringUtils(Apache Commons Lang)
希望有帮助。使用
String。用^abc
替换first
(以匹配前导abc
)
一个不使用正则表达式的解决方案(我之所以需要它,是因为我要删除的字符串是可配置的,并且包含反斜杠,在正则表达式中需要转义以便在文本中使用):
Apache Commons Lang将使用String.startsWith
和String.substring
从str
的开头删除remove
该方法的主要功能是提供信息:
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;
}
如果您关心性能,您可以通过使用相同的预编译前缀
模式
来匹配多个字符串,从而改进str.replaceFirst(“^abc”,”)
解决方案
final Pattern prefix = Pattern.compile("^abc"); // Could be static constant etc
for ... {
final String result = prefix.matcher(str).replaceFirst("");
}
我想如果你从很多字符串中去掉相同的前缀,差别会很明显。谢谢,但我没有描述我使用此方法的整个上下文,因此我不认为你可以声称我不应该“在这种情况下浪费时间提高效率”。这里有几个答案建议
str.replaceFirst(^abc)“,”)
。这会相当有效吗?@barakmanos您计划使用多少字符串?10000000000(需要再添加几个0才能添加此注释,但仍然有很多)谢谢ᴍaroun
。它应该是replaceFirst
,而不是replaceAll
。此外,请注意,startsWith(…)
的任何使用都必须后跟子字符串(…)
和length()
,您在上面的测试中没有考虑到这一点。我将发布一个关于replaceFirst
性能的单独问题,并查看答案(尽管我可能会使用您在上面的建议来经验性地断言这一点)。如果字符串类似于“123abcxyz”`它将变成“123xyz”
如果是这种情况,那么此解决方案对我不起作用。您对“abc”不同职位的预期输出是什么
?我已经稍微编辑了正则表达式,以确保abc
从开头剥离,否则字符串将保持不变。如果字符串由于锚的存在而没有以abc
开头,它将立即停止。^这将只“切断”前缀“abc”
,如果存在这样一个?^使其在开始时仅与abc匹配“123abc456”如何。replaceFirst(^abc),“)
?是否将replaceFirst
进行“彻底搜索”,或者它会立即停止,因为“^”
?@barakmanos,^
只在输入字符串的开头匹配。我没有检查replaceFirst
;我不确定它是否会进行彻底搜索,但我想不会。担心“效率”在这里是相当愚蠢的,除非你试图每X执行数百万次,这是瓶颈。你的代码,按原样,读起来很好并传达了意图。我的前缀包含下划线,我真的不喜欢使用双反斜杠来转义。第一个反斜杠用于Java编译器,第二个反斜杠用于Regexp编译器。
final Pattern prefix = Pattern.compile("^abc"); // Could be static constant etc
for ... {
final String result = prefix.matcher(str).replaceFirst("");
}