web-dev-qa-db-fra.com

Java chaîne remplace et le caractère NUL (NULL, ASCII 0)?

En testant le code d'un autre utilisateur, j'ai remarqué quelques pages JSP imprimant des caractères géniaux non ASCII. En plongeant dans la source, j'ai trouvé cette friandise:

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

Le remplacement d'un caractère dans une chaîne par un caractère nul fonctionne-t-il même en Java? Je le sais '\0' terminera une chaîne C. Serait-ce le coupable des personnages funky?

31
praspa

Le remplacement d'un caractère dans une chaîne par un caractère nul fonctionne-t-il même en Java? Je sais que '\ 0' terminera une chaîne de caractères.

Cela dépend de la façon dont vous définissez ce qui fonctionne. Remplace-t-il toutes les occurrences du personnage cible par '\0'? Absolument!

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"

Tout semble bien fonctionner pour moi! indexOf peut le trouver, il compte comme partie de la longueur et sa valeur pour le calcul du code de hachage est 0; tout est comme spécifié par JLS/API.

Cela NE FONCTIONNE PAS si vous vous attendez à ce que le remplacement d'un caractère par le caractère nul supprime en quelque sorte ce caractère de la chaîne. Bien sûr, cela ne fonctionne pas comme ça. Un caractère nul est toujours un caractère!

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

Cela fonctionne également NE FONCTIONNE PAS si vous vous attendez à ce que le caractère nul termine une chaîne. Cela ressort des extraits ci-dessus, mais il est également clairement spécifié dans JLS ( 10.9. Un tableau de caractères n'est pas une chaîne ):

Dans le langage de programmation Java, contrairement à C, un tableau de char n'est pas un String, ni un String ni un tableau de char se termine par '\ u0000' (le caractère NUL).


Serait-ce le coupable des personnages funky?

Maintenant, nous parlons d'une chose entièrement différente, c'est-à-dire comment la chaîne est rendue à l'écran. La vérité est, même "Bonjour tout le monde!" aura l'air génial si vous utilisez la police dingbats. Une chaîne unicode peut sembler géniale dans un endroit mais pas dans l'autre. Même une chaîne Unicode correctement rendue contenant, par exemple, des caractères chinois, peut toujours sembler géniale à quelqu'un du Groenland, par exemple.

Cela dit, le caractère nul aura probablement l'air génial malgré tout; ce n'est généralement pas un caractère que vous souhaitez afficher. Cela dit, puisque le caractère nul n'est pas le terminateur de chaîne, Java est plus que capable de le gérer d'une manière ou d'une autre.


Maintenant, pour répondre à ce que nous supposons être l'effet recherché, c'est-à-dire supprimer tous les points d'une chaîne, la solution la plus simple consiste à utiliser la surcharge replace(CharSequence, CharSequence).

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

La solution replaceAll est également mentionnée ici, mais cela fonctionne avec l'expression régulière, c'est pourquoi vous devez échapper le caractère méta point, et est susceptible d'être plus lent.

83
polygenelubricants

Devrait probablement être changé en

firstName = firstName.trim().replaceAll("\\.", "");
8
Roman

Le remplacement d'un caractère dans une chaîne par un caractère nul fonctionne-t-il même en Java?

Non.

Serait-ce le coupable des personnages funky?

Plutôt probable.

4
Michael Borgwardt

Je pense que ça devrait être le cas. Pour effacer le caractère, vous devez utiliser replace(".", "") à la place.

4
Valentin Rocher

Cela provoque des "personnages funky":

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

produit:

Mr[] Foo

dans ma console Eclipse, où le [] est affiché sous forme de boîte carrée. Comme d'autres l'ont publié, utilisez String.replace().

2
Jim Ferrans