はじめに
Character.isSpaceChar()
と Character.isWhitespace()
はいずれも引数の文字がスペースかどうかを判定する static メソッドだが、その違いは?
文字列の前後のスペースを削除するには String.trim()
がよく使われてきたが、同じようなものに String.strip()
がある。その違いは?
スペースの定義の違い
Character.isSpaceChar()
は、Unicode の Zs(Space Separator)、Zl(Line Separator)、Zp(Paragraph Separator) カテゴリでtrue
となるCharacter.isWhitespace()
は、Character.isSpaceChar()
に加え(ただしNo-Breakを除く)、Cc(Control)カテゴリの一部でtrue
となるString.strip()
は、Character.isWhitespace()
がtrue
のものが削除対象String.trim()
は、ASCII の制御コード部分(U+0020
より小さいもの)が削除対象U+200B
やU+FEFF
は、いずれの場合も空白として判断されない
まとめると以下の表になる。
注意すべきものは赤字。
カテゴリ | Code Point | Name | 説明 | isSpaceChar() | isWhitespace() / strip() | trim() |
---|---|---|---|---|---|---|
Zs | U+0020 |
Space | 半角スペース 通常は 1/4 em の幅 | 〇 | 〇 | 〇 |
Zs | U+00A0 |
No-Break Space |   Space と同じ幅。No-Break |
〇 | ✗ | ✗ |
Zs | U+1680 |
Ogham Space mark | オガム文字のスペース(ダッシュで表示される) | 〇 | 〇 | ✗ |
Zs | U+180E |
Mongolian Vowel Separator | モンゴル語の母音区切り | 〇 | 〇 | ✗ |
Zs | U+2000 |
En Quad | 1/2 em 幅 | 〇 | 〇 | ✗ |
Zs | U+2001 |
Em Quad | 1 em 幅 (フォントの高さと同じ) | 〇 | 〇 | ✗ |
Zs | U+2002 |
En Space |   1/2 em |
〇 | 〇 | ✗ |
Zs | U+2003 |
Em Space |   1 em |
〇 | 〇 | ✗ |
Zs | U+2004 |
Three-Per-Em Space | 1/3 em | 〇 | 〇 | ✗ |
Zs | U+2005 |
Four-Per-Em Space | 1/4 em | 〇 | 〇 | ✗ |
Zs | U+2006 |
Six-Per-Em Space | 1/6 em | 〇 | 〇 | ✗ |
Zs | U+2007 |
Figure Space(No-Break) | 固定幅フォントの数字と同じ幅。No-Break | 〇 | ✗ | ✗ |
Zs | U+2008 |
Punctuation Space | ピリオドの幅 | 〇 | 〇 | ✗ |
Zs | U+2009 |
Thin Space |   1/5 em |
〇 | 〇 | ✗ |
Zs | U+200A |
Hair Space | Thin Space よりさらに狭い | 〇 | 〇 | ✗ |
Zs | U+202F |
Narrow No-Break Space | 狭い  。No-Break |
〇 | ✗ | ✗ |
Zs | U+205F |
Medium Mathematical Space | 4/18 em (Unicode 4.0〜) | 〇 | 〇 | ✗ |
Zs | U+3000 |
Idepgraphic Space | 全角スペース | 〇 | 〇 | ✗ |
Zl | U+2028 |
Line Separator | Unicodeの行区切り文字 | 〇 | 〇 | ✗ |
Zp | U+2029 |
Paragraph Separator | Unicodeの段落区切り文字 | 〇 | 〇 | ✗ |
Cc | U+0000 |
Null | NUL | ✗ | ✗ | 〇 |
Cc | ... | ✗ | ✗ | 〇 | ||
Cc | U+0008 |
Backspace | BS | ✗ | ✗ | 〇 |
Cc | U+0009 |
Character Tabulation | 水平タブ \t |
✗ | 〇 | 〇 |
Cc | U+000A |
End of Line | 改行 \n |
✗ | 〇 | 〇 |
Cc | U+000B |
Line Tabulation | 垂直タブ | ✗ | 〇 | 〇 |
Cc | U+000C |
Form Feed | フォーム・フィード \f |
✗ | 〇 | 〇 |
Cc | U+000D |
Carriage Return | 復帰 \r |
✗ | 〇 | 〇 |
Cc | U+000E |
Locking-Shift One | ✗ | ✗ | 〇 | |
Cc | ... | ✗ | ✗ | 〇 | ||
Cc | U+001B |
Escape | ESC | ✗ | ✗ | 〇 |
Cc | U+001C |
File Separator | ファイル区切り文字 | ✗ | 〇 | 〇 |
Cc | U+001D |
Group Separator | グループ区切り文字 | ✗ | 〇 | 〇 |
Cc | U+001E |
Information Separator Two | レコード区切り文字 | ✗ | 〇 | 〇 |
Cc | U+001F |
Information Separator One | 単位区切り文字 | ✗ | 〇 | 〇 |
Cc | U+007F |
Delete | DEL | ✗ | ✗ | ✗ |
Cc | ... | ✗ | ✗ | ✗ | ||
Cc | U+009F |
Application Program Command | APC | ✗ | ✗ | ✗ |
Cf | U+200B |
Zero Width Space | ゼロ幅のスペース | ✗ | ✗ | ✗ |
Cf | U+FEFF |
Zero Width No-Break Space | ゼロ幅の   |
✗ | ✗ | ✗ |
スペースっぽいもの全てを切り捨てる
よくわからないスペースや制御文字を除きたい場合は、バッサリと以下で判断してしまえば良い。
public static String strip(String string) { return string.codePoints() .filter(cp -> !isBlank(cp)) .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) .toString(); } public static boolean isBlank(int cp) { return Character.isSpaceChar(cp) || Character.isISOControl(cp) || cp == '\u200B'|| cp == '\uFEFF'; }
Character.isISOControl()
はCc(Control)カテゴリのものでtrue
U+200B
とU+FEFF
はスペースのカテゴリ外でたまに問題になるので削除しておくと安全