用 Java 修剪字符

如何修剪 Java 中的字符?
例如:。

String j = “\joe\jill\”.Trim(new char[] {“\”});

应该是

“ Joe Jill”

String j = “jack\joe\jill\”.Trim("jack");

应该是

“ Joe Jill”

等等

155997 次浏览

编辑 : 由答案修改为只替换第一个和最后一个’’字符。

System.err.println("\\joe\\jill\\".replaceAll("^\\\\|\\\\$", ""));

我不认为有任何内置的功能,以修剪基于传递的字符串。这里有一个如何做到这一点的小例子。这可能不是最有效的解决方案,但对于大多数情况来说,它可能足够快,可以评估和适应您的需求。我建议对任何经常使用的代码片段进行性能测试和优化。下面,我已经包含了一些计时信息作为示例。

public String trim( String stringToTrim, String stringToRemove )
{
String answer = stringToTrim;


while( answer.startsWith( stringToRemove ) )
{
answer = answer.substring( stringToRemove.length() );
}


while( answer.endsWith( stringToRemove ) )
{
answer = answer.substring( 0, answer.length() - stringToRemove.length() );
}


return answer;
}

这个答案假设要裁剪的字符是一个字符串。例如,传入“ abc”将删除“ abc”,而不是“ bbc”或“ cba”等。

运行以下每个程序的一些性能时间为1000万次。

" mile ".trim();运行速度为248毫秒

trim( "smiles", "s" );的运行时间为547毫秒——大约是 java 的 String.trim()方法的2倍。

"smiles".replaceAll("s$|^s","");运行时间为12,306 ms ——大约是 java 的 String.trim()方法的48倍。

并使用已编译的正则表达式模式 Pattern pattern = Pattern.compile("s$|^s"); pattern.matcher("smiles").replaceAll("");的运行时间为7,804 ms ——大约是 java 的 String.trim()方法的31倍。

似乎还没有准备好使用 java api 来实现这一点,但是您可以编写一个方法来实现这一点。 这个 链接可能有用

这就是你想要的:

public static void main (String[] args) {
String a = "\\joe\\jill\\";
String b = a.replaceAll("\\\\$", "").replaceAll("^\\\\", "");
System.out.println(b);
}

$用于删除字符串末尾的序列。^用于在开始时移除。

作为替代方法,您可以使用以下语法:

String b = a.replaceAll("\\\\$|^\\\\", "");

|的意思是“或者”。

如果您想修剪其他字符,只需调整 regex:

String b = a.replaceAll("y$|^x", ""); // will remove all the y from the end and x from the beggining

您可以使用 Apache Commons Lang StringUtils中的 removeStartremoveEnd

手工制作的第一种选择:

public class Rep {
public static void main( String [] args ) {
System.out.println( trimChar( '\\' , "\\\\\\joe\\jill\\\\\\\\" )  ) ;
System.out.println( trimChar( '\\' , "joe\\jill" )  ) ;
}
private static String trimChar( char toTrim, String inString ) {
int from = 0;
int to = inString.length();


for( int i = 0 ; i < inString.length() ; i++ ) {
if( inString.charAt( i ) != toTrim) {
from = i;
break;
}
}
for( int i = inString.length()-1 ; i >= 0 ; i-- ){
if( inString.charAt( i ) != toTrim ){
to = i;
break;
}
}
return inString.substring( from , to );
}
}

指纹

joe\jil

joe\jil

实际上,我会编写自己的小函数,通过使用普通的 char 访问来完成这个任务:

public static String trimBackslash( String str )
{
int len, left, right;
return str == null || ( len = str.length() ) == 0
|| ( ( left = str.charAt( 0 ) == '\\' ? 1 : 0 ) |
( right = len > left && str.charAt( len - 1 ) == '\\' ? 1 : 0 ) ) == 0
? str : str.substring( left, len - right );
}

这个函数的行为类似于 String.trim () ,只不过它使用的是’而不是空格。

这里有一个可行的替代方案,它实际上使用了 trim ()。;)尽管效率不是很高,但在性能方面可能胜过所有基于 regexp 的方法。

String j = “\joe\jill\”;
j = j.replace( '\\', '\f' ).trim().replace( '\f', '\\' );

Apache Commons 有一个很棒的 StringUtils 类(org.Apache.Commons. lang。StringUtils).在 StringUtils中有一个 strip(String, String)方法,它可以做你想做的事情。

我强烈推荐使用 ApacheCommons,特别是 Collection 和 Lang 库。

CharMatcher-谷歌番石榴

过去,我支持 柯林斯的阿帕奇语回答。但是现在 Google 的 番石榴图书馆已经发布了,CharMatcher类可以很好地满足你的需求:

String j = CharMatcher.is('\\').trimFrom("\\joe\\jill\\");
// j is now joe\jill

CharMatcher 有一组非常简单和强大的 API 以及一些预定义的常量,这些常量使操作变得非常容易。例如:

CharMatcher.is(':').countIn("a:b:c"); // returns 2
CharMatcher.isNot(':').countIn("a:b:c"); // returns 3
CharMatcher.inRange('a', 'b').countIn("a:b:c"); // returns 2
CharMatcher.DIGIT.retainFrom("a12b34"); // returns "1234"
CharMatcher.ASCII.negate().removeFrom("a®¶b"); // returns "ab";

非常好的东西。

我会这么做。

我认为它已经尽可能的高效了。它优化了单个字符的大小写,避免了为每个删除的子序列创建多个子字符串。

请注意,处理了传递空字符串以进行修剪的角落情况(其他一些答案将进入无限循环)。

/** Trim all occurrences of the string <code>rmvval</code> from the left and right of <code>src</code>.  Note that <code>rmvval</code> constitutes an entire string which must match using <code>String.startsWith</code> and <code>String.endsWith</code>. */
static public String trim(String src, String rmvval) {
return trim(src,rmvval,rmvval,true);
}


/** Trim all occurrences of the string <code>lftval</code> from the left and <code>rgtval</code> from the right of <code>src</code>.  Note that the values to remove constitute strings which must match using <code>String.startsWith</code> and <code>String.endsWith</code>. */
static public String trim(String src, String lftval, String rgtval, boolean igncas) {
int                                 str=0,end=src.length();


if(lftval.length()==1) {                                                    // optimize for common use - trimming a single character from left
char chr=lftval.charAt(0);
while(str<end && src.charAt(str)==chr) { str++; }
}
else if(lftval.length()>1) {                                                // handle repeated removal of a specific character sequence from left
int vallen=lftval.length(),newstr;
while((newstr=(str+vallen))<=end && src.regionMatches(igncas,str,lftval,0,vallen)) { str=newstr; }
}


if(rgtval.length()==1) {                                                    // optimize for common use - trimming a single character from right
char chr=rgtval.charAt(0);
while(str<end && src.charAt(end-1)==chr) { end--; }
}
else if(rgtval.length()>1) {                                                // handle repeated removal of a specific character sequence from right
int vallen=rgtval.length(),newend;
while(str<=(newend=(end-vallen)) && src.regionMatches(igncas,newend,rgtval,0,vallen)) { end=newend; }
}


if(str!=0 || end!=src.length()) {
if(str<end) { src=src.substring(str,end); }                            // str is inclusive, end is exclusive
else        { src="";                     }
}


return src;
}

下面是另一个非 regexp、非超级棒、非超级优化、但非外部 lib 解决方案非常容易理解的解决方案:

public static String trimStringByString(String text, String trimBy) {
int beginIndex = 0;
int endIndex = text.length();


while (text.substring(beginIndex, endIndex).startsWith(trimBy)) {
beginIndex += trimBy.length();
}


while (text.substring(beginIndex, endIndex).endsWith(trimBy)) {
endIndex -= trimBy.length();
}


return text.substring(beginIndex, endIndex);
}

用法:

String trimmedString = trimStringByString(stringToTrim, "/");
public static String trim(String value, char c) {


if (c <= 32) return value.trim();


int len = value.length();
int st = 0;
char[] val = value.toCharArray();    /* avoid getfield opcode */


while ((st < len) && (val[st] == c)) {
st++;
}
while ((st < len) && (val[len - 1] == c)) {
len--;
}
return ((st > 0) || (len < value.length())) ? value.substring(st, len) : value;
}

10年前的问题,但觉得大多数答案有点复杂或不太工作的方式问。此外,这里投票最多的答案也没有提供任何例子。下面是我做的一个简单的类:

Https://gist.github.com/maxdw/d71afd11db2df4f1297ad3722d6392ec

用法 :

Trim.left("\joe\jill\", "\") == "joe\jill\"


Trim.left("jack\joe\jill\", "jack") == "\joe\jill\"


Trim.left("\\\\joe\\jill\\\\", "\") == "joe\\jill\\\\"

我的解决办法是:

private static String trim(String string, String charSequence) {
var str = string;
str = str.replace(" ", "$SAVE_SPACE$").
replace(charSequence, " ").
trim().
replace(" ", charSequence).
replace("$SAVE_SPACE$", " ");
return str;
}