Причина, по которой вы продолжаете искать разные техники, состоит в том, чтобы найти ту, которая действительно соответствует вашим желаниям.Например, trim()
удаляет только пробелы в начале и конце строки.Чтобы получить тот же эффект с регулярным выражением, вы должны сделать что-то вроде этого:
s = s.replaceAll("^\\s+|\\s+$", "");
И еще вопрос, какие именно символы будут удалены.До Java 7 \s
соответствует только пробельным символам ASCII, то есть:
"[\\u0009\\u000A\\u000B\\u000C\\u000D\\u0020]"
... в то время как (как заметил Питер) trim()
простым способом удаляет все символы с кодовой точкой 32 или ниже (U+0020
в нотации Unicode).Я подозреваю, что мысль здесь заключалась в том, что другие символы крайне маловероятно появляются в строке в любом случае, и если они это сделают, вы, вероятно, захотите избавиться от них.(В любом случае, это работает для меня. ☺) Но это то, что вы должны знать.Вот некоторый код, который демонстрирует разницу между trim()
и подходом регулярных выражений:
String s = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007"
+ "\u0008\u0009\n\u000B\u000C\r\u000E\u000F"
+ "\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017"
+ "\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F"
+ "\u0020\u00A0";
System.out.println(s.length());
System.out.println(s.trim().length());
System.out.println(s.replaceAll("\\s", "").length());
output:
34
1
28
Один оставшийся символ во второй строке вывода не являетсяпробел (U+00A0
, или далее «NBSP»).Когда вы выйдете за пределы диапазона ASCII, станет намного больше пробельных символов, но чаще всего встречается NBSP.Ни trim()
, ни регулярное выражение не удалили его, но посмотрите, что произойдет, если вы измените последнюю строку кода на это:
System.out.println(s.replaceAll("(?U)\\s", "").length());
... и запустите его под Java 7:
34
1
27
Добавив (?U)
, я включил режим UNICODE_CHARACTER_CLASSES
, как упоминал @tchrist в своем комментарии.NBSP - это символ пробела, независимо от того, что говорит Character.isWhitespace()
, но это не значит, что вы всегда захотите включить его в совпадения пробелов.Вот почему Guava (упомянутый @Sean) также включает BREAKING_WHITESPACE CharMatcher.
В сумме, чтобы выбрать правильный инструмент для удаления пробелов, вам нужно точно знать, какие символы пробелов вы хотите использоватьудалить, и именно там, где вы хотите удалить их.Это не так уж сложно, но не так просто, как унаследованные инструменты, такие как trim()
, и StringTokenizer делают вид, что это тоже.