tags:

views:

113

answers:

5

I'm using a framwork which returns malformed Strings with "empty" characters from time to time.

"foobar" for example is represented by: [,f,o,o,b,a,r]

The first character is NOT a whitespace (' '), so a System.out.printlin() would return "foobar" and not " foobar". Yet, the length of the String is 7 instead of 6. Obviously this makes most String methods (equals, split, substring,..) useless. Is there a way to remove empty characters from a String?

I tried to build a new String like this:

StringBuilder sb = new StringBuilder();
for (final char character : malformedString.toCharArray()) {
  if (Character.isDefined(character)) {
    sb.append(character);
  }
}
sb.toString();

Unfortunately this doesn't work. Same with the following code:

StringBuilder sb = new StringBuilder();
for (final Character character : malformedString.toCharArray()) {
  if (character != null) {
    sb.append(character);
  }
}
sb.toString();

I also can't check for an empty character like this:

   if (character == ''){
     //
   }

Obviously there is something wrong with the String .. but I can't change the framework I'm using or wait for them to fix it (if it is a bug within their framework). I need to handle this String and sanatize it.

Any ideas?

+1  A: 

trim left or right removes white spaces. does it has a colon before space?

even more: a=(long) string[0]; will show u the char code, and u can use replace() or substring.

ESP
+2  A: 

It's probably the NULL character which is represented by \0. You can get rid of it by String#trim().

To nail down the exact codepoint, do so:

for (char c : string.toCharArray()) {
    System.out.printf("U+%04x ", (int) c);
}

Then you can find the exact character here.


Update: as per the update:

Anyone know of a way to just include a range of valid characters instead of excluding 95% of the UTF8 range?

You can do that with help of regex. See the answer of @polygenelubricants here and this answer.

On the other hand, you can also just fix the problem in its root instead of workarounding it. Either update the files to get rid of the BOM mark, it's a legacy way to distinguish UTF-8 files from others which is nowadays worthless, or use a Reader which recognizes and skips the BOM. Also see this question.

BalusC
+1 for the debugging tip. Eliminates all guessworks.
polygenelubricants
A: 

You could check for the whitespace like this:

if (character.equals(' ')){ // }
The question already establishes that the character is not a space.
Nick
The question does say that it is not whitespace; however, in the three code examples given he is using comparison operators to check for the character, and if I am not mistaken you cannot use comparison operators to check for a certain character because they are checking if you are referencing the same place in memory not the character code. It was just a helpful suggestion / option based on the code provided.
I see where you're coming from - for a Character object, using equals() is the right thing to do. I tend to keep to chars when dealing which characters, and with a char you *can* use == since it's a primitive type.
Nick
A: 

Thank you Johannes Rössel. It actually was '\uFEFF'

The following code works:

 final StringBuilder sb = new StringBuilder();
    for (final char character : body.toCharArray()) {
       if (character != '\uFEFF') {
          sb.append(character);
       }
     }  
 final String sanitzedString = sb.toString();

Anyone know of a way to just include a range of valid characters instead of excluding 95% of the UTF8 range?

black666
You should then define "valid characters" more precisely.
BalusC
this is inefficient, just check if the first character is FEFF and use substring, `String.trim()` will do the rest.
tulskiy
+1  A: 

Regex would be an appropriate way to sanitize the string from unwanted Unicode characters in this case.

String sanitized = dirty.replaceAll("[\uFEFF-\uFFFF]", ""); 

This will replace all char in \uFEFF-\uFFFF range with the empty string.

The [...] construct is called a character class, e.g. [aeiou] matches one of any of the lowercase vowels, [^aeiou] matches anything but.

You can do one of these two approaches:

  • replaceAll("[blacklist]", "")
  • replaceAll("[^whitelist]", "")

References

polygenelubricants