私はJ2MEアプリケーション用にこの関数を書いているので、より高度な/モダンなJavaクラスを利用できません。これでJava.lang.ArrayIndexOutOfBoundsException
を取得しています。 、明らかにnewChars
配列を初期化した方法が気に入らないか、System.arraycopy
を呼び出したときに何かを正しく行っていません。
/*
* remove any leading and trailing spaces
*/
public static String trim(String str) {
char[] chars = str.toCharArray();
int len = chars.length;
// leading
while ( (len > 0 ) && ( chars[0] == ' ' ) ) {
char[] newChars = new char[] {}; // initialize empty array
System.arraycopy(chars, 1, newChars, 0, len - 1);
chars = newChars;
len = chars.length;
}
// TODO: trailing
return chars.toString();
}
先頭および末尾の空白を削除する簡単な方法は、 String.trim()
を呼び出すことです。 (先頭と末尾のすべての空白ではなく)先頭と末尾のスペースだけをトリムしたい場合、これを行うことができる StringUtils.strip(String, String)
というApache commonsメソッドがあります。 2番目の引数として_" "
_を指定して呼び出します。
試みたコードには多くのバグがあり、根本的に非効率的です。本当にこれを自分で実装したい場合は、次のようにする必要があります。
String.substring(from, end)
を呼び出して、保持する文字を含む新しい文字列を作成します。このアプローチは、文字のコピーを回避します1。
1-実際、それはString
の実装に依存します。一部の実装ではコピーが行われず、他の実装では単一のコピーが作成されます。ただし、どちらもアプローチの改善であり、これには最低2つのコピーが必要であり、トリミングする文字がある場合はさらに多くなります。
String.trim()
は非常に古く、少なくともJava 1.3。これはありませんか?
Apache StringUtils.strip は、(スペースだけでなく)予想されるすべての空白文字で動作するベストアンサーです。 ここからダウンロードできます :
関連するコードは次のとおりです このソースファイルからリッピング 必要に応じて独自のクラスに実装しますが、実際には、StringUtilsをダウンロードして使用するだけで、より大きな価値を得ることができます! StringUtils.stripStart
を使用して、Java文字列から先頭の文字をトリミングすることもできます。
public static final int INDEX_NOT_FOUND = -1
public static String strip(final String str) {
return strip(str, null);
}
public static String stripStart(final String str, final String stripChars) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return str;
}
int start = 0;
if (stripChars == null) {
while (start != strLen && Character.isWhitespace(str.charAt(start))) {
start++;
}
} else if (stripChars.isEmpty()) {
return str;
} else {
while (start != strLen && stripChars.indexOf(str.charAt(start)) != INDEX_NOT_FOUND) {
start++;
}
}
return str.substring(start);
}
public static String stripEnd(final String str, final String stripChars) {
int end;
if (str == null || (end = str.length()) == 0) {
return str;
}
if (stripChars == null) {
while (end != 0 && Character.isWhitespace(str.charAt(end - 1))) {
end--;
}
} else if (stripChars.isEmpty()) {
return str;
} else {
while (end != 0 && stripChars.indexOf(str.charAt(end - 1)) != INDEX_NOT_FOUND) {
end--;
}
}
return str.substring(0, end);
}
public static String strip(String str, final String stripChars) {
if (isEmpty(str)) {
return str;
}
str = stripStart(str, stripChars);
return stripEnd(str, stripChars);
}
JDK/11では、String.strip
この文字列を値とする文字列を返すAPI。先頭および末尾の空白はすべて削除されます。同じためのjavadocは次のとおりです。
/**
* Returns a string whose value is this string, with all leading
* and trailing {@link Character#isWhitespace(int) white space}
* removed.
* <p>
* If this {@code String} object represents an empty string,
* or if all code points in this string are
* {@link Character#isWhitespace(int) white space}, then an empty string
* is returned.
* <p>
* Otherwise, returns a substring of this string beginning with the first
* code point that is not a {@link Character#isWhitespace(int) white space}
* up to and including the last code point that is not a
* {@link Character#isWhitespace(int) white space}.
* <p>
* This method may be used to strip
* {@link Character#isWhitespace(int) white space} from
* the beginning and end of a string.
*
* @return a string whose value is this string, with all leading
* and trailing white space removed
*
* @see Character#isWhitespace(int)
*
* @since 11
*/
public String strip()
これらのサンプルケースは次のとおりです。
System.out.println("".strip());
System.out.println(" both ".strip());
System.out.println(" leading".strip());
System.out.println("trailing ".strip());
まず、他の人がString.trim()
について言ったこと。本当に、車輪を再発明しないでください。
しかし、記録の場合、コードの問題は、Java配列はサイズ変更できないことです。ターゲット配列を最初にセットアップするとき、サイズ0配列として作成します。 System.arraycopy
スタッフにlen - 1
文字があります。それはうまくいきません。動作させたい場合は、配列を次のように設定する必要があります。
char[] newChars = new char[len - 1];
しかし、それは驚くほど非効率的で、ループを通るたびに新しい配列を再割り当てしてコピーします。 Stephen Cが言及した3つのステップを使用し、最後にsubstring
を付けます。
String.trim()メソッドを使用したくない場合は、以下のように実装できます。ロジックは、スペース、タブ、その他の特殊文字などのさまざまなシナリオを処理します。
public static String trim(String str){
int i=0;
int j = str.length();
char[] charArray = str.toCharArray();
while((i<j) && charArray[i] <=' '){
i++;
}
while((i<j) && charArray[j-1]<= ' '){
j--;
}
return str.substring(i, j+1);
}
public static void main(String[] args) {
System.out.println(trim(" abcd ght trip "));
}
Guava CharMatcher を使用できます。
String outputString = CharMatcher.whitespace().trimFrom(inputString);
注:空白はすべてBMPに含まれているため、これは機能します。
コピー先の配列newCharsは、コピーされた値を保持するのに十分な大きさではありません。コピーするデータの長さ(つまり、長さ-1)に初期化する必要があります。