Java заменить строку и символ NUL (NULL, ASCII 0)? - PullRequest
31 голосов
/ 26 марта 2010

Тестируя кто-то еще, я заметил несколько страниц JSP, печатающих прикольные символы не ASCII. Окунувшись в источник, я нашел этот кусочек:

// remove any periods from first name e.g. Mr. John --> Mr John
firstName = firstName.trim().replace('.','\0');

Работает ли замена символа в строке нулевым символом даже в Java? Я знаю, что '\0' завершит C-строку. Будет ли это виновником забавных персонажей?

Ответы [ 5 ]

82 голосов
/ 26 марта 2010

Работает ли замена символа в строке на нулевой символ даже в Java? Я знаю, что '\ 0' завершит к-строку.

Это зависит от того, как вы определяете, что работает. Заменяет ли он все вхождения целевого персонажа на '\0'? Абсолютно!

String s = "food".replace('o', '\0');
System.out.println(s.indexOf('\0')); // "1"
System.out.println(s.indexOf('d')); // "3"
System.out.println(s.length()); // "4"
System.out.println(s.hashCode() == 'f'*31*31*31 + 'd'); // "true"

Мне кажется, все работает нормально! indexOf может найти его, он считается частью длины, и его значение для вычисления хеш-кода равно 0; все как указано в JLS / API.

Это НЕ ДЕЙСТВУЕТ , если вы ожидаете, что замена символа нулевым символом каким-то образом удалит этот символ из строки. Конечно, это не работает так. Нулевой символ по-прежнему символ!

String s = Character.toString('\0');
System.out.println(s.length()); // "1"
assert s.charAt(0) == 0;

Также НЕ РАБОТАЕТ , если ожидается, что нулевой символ завершит строку. Это видно из приведенных выше фрагментов, но также четко указано в JLS ( 10.9. Массив символов не является строкой ):

В языке программирования Java, в отличие от C, массив char не является String, и ни String, ни массив char не заканчиваются на '\ u0000' (символ NUL) .


Будет ли это виновником прикольных персонажей?

Теперь мы говорим о совершенно другой вещи, то есть о том, как строка отображается на экране. Правда, даже "Привет, мир!" будет выглядеть прикольным, если вы используете шрифт dingbats. Строка Unicode может выглядеть странно в одной локали, но не в другой. Даже правильно отрисованная строка в юникоде, содержащая, скажем, китайские иероглифы, может все же выглядеть странно для кого-то, скажем, из Гренландии.

Тем не менее, нулевой символ, вероятно, будет выглядеть в стиле фанк независимо; обычно это не персонаж, который вы хотите отобразить. Тем не менее, поскольку нулевой символ не является ограничителем строки, Java более чем способна обработать его так или иначе.


Теперь для решения предполагаемого эффекта, то есть удаления всего периода из строки, самое простое решение - использовать перегрузку replace(CharSequence, CharSequence).

System.out.println("A.E.I.O.U".replace(".", "")); // AEIOU

Здесь также упоминается решение replaceAll, но оно работает с регулярным выражением, поэтому вам нужно экранировать метасимвол точки и, вероятно, будет медленнее.

8 голосов
/ 26 марта 2010

Должно быть вероятно изменено на

firstName = firstName.trim().replaceAll("\\.", "");
4 голосов
/ 26 марта 2010

Я думаю, что так и должно быть. Чтобы стереть символ, вы должны использовать replace(".", "") вместо.

4 голосов
/ 26 марта 2010

Работает ли замена символа в строке на нулевой символ даже в Java?

Нет.

Будет ли это виновником фанка?символы?

Вполне вероятно.

1 голос
/ 26 марта 2010

Это вызывает "фанки персонажей":

System.out.println( "Mr. Foo".trim().replace('.','\0'));

производит:

Mr[] Foo

в моей консоли Eclipse, где [] отображается в виде квадратной рамки. Как и другие опубликовали, используйте String.replace().

...