48

We are getting properties (that we can not influence) out of a database and want to access them by a key/value mapping. We are facing the problem that one of the property keys includes a blank character.

foo bar = barefoot

This is - correctly - interpreted as follows

key: foo
value: bar = barefoot

Is there a way to include the blank in the key so that it's not interpreted as the delimiter? I guess this behaviour is just like intended, but I thought I could give it a try here.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
bl4ckb0l7
  • 3,839
  • 4
  • 28
  • 33
  • 3
    It's right there in the docs: http://java.sun.com/javase/6/docs/api/java/util/Properties.html#load(java.io.Reader) – T.J. Crowder Jan 21 '10 at 09:40

5 Answers5

177

You can escape every thing in properties file with Java Unicode:

  • \u003d for =
  • \u0020 for whitespace

For example:

foo bar = barefoot

must be:

foo\u0020bar\u0020=\u0020barefoot

So will be:

key: "foo bar "
value: " barefoot"
bluish
  • 26,356
  • 27
  • 122
  • 180
Veaceslav Serghienco
  • 1,880
  • 2
  • 12
  • 6
  • 13
    This is the "Correct" answer. All other options will end up with non standard solutions. PLEASE use this answer :) – Yinzara Nov 13 '13 at 00:03
  • 1
    Note that this seems not to work in Grails configuration files (not .groovy but .properties; tested on 2.5.1). – Newerth Oct 07 '15 at 14:18
  • 1
    Good solution. Note however that OP writes they "can not influence" the properties they get, so escaping may not be practical. Of course maybe it's possible to have some preprocessing step to do it... – sleske Jul 05 '17 at 04:54
  • Agree this is the correct answer assuming you can modify the properties file. – Jeremy May 17 '18 at 13:11
  • If the OP could change the properties file, then he could simply make it foo.bar instead of foo bar avoid the rather messy use of Unicode characters. However, the OP stated that properties could not be altered so this doesn't solve the given issue. – ManoDestra Nov 06 '18 at 15:01
16

Maybe you can escape the whitespaces: foo\ bar = barefoot

Edit: Oops, I did not see that you can't change the properties.

Petar Minchev
  • 46,889
  • 11
  • 103
  • 119
  • Escaping whitespaces will not work with most editors that trim spaces at the end of lines by default - think of a mainframe parameter that needs trailing spaces. Correct is Veaceslav's solution. – Zero Distraction Oct 15 '14 at 00:39
11

As it seems the delimiter should be =, not space. Hence - keyValuePair.split("=") should do.

If you are loading this from a java .properties file, then you can extend java.util.Properties and override this method

public synchronized void load(InputStream inStream) throws IOException

so that it parses the properties correctly.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 2
    Hm, overriding methods in `Properties` seems dubios at best. There are probably many hardcoded assumptions in the Properties class, so it's a source of future bugs. If it's not a proper Properties file, i'd rather not use Properties to read it. – sleske Jan 21 '10 at 16:53
  • At least a try should be given, because it would save a lot of time. If it doesn't work - create a separate properties parse of course – Bozho Jan 21 '10 at 17:07
  • How do you set `keyValuePair.split("=")`? – Xonatron Nov 15 '12 at 17:35
  • I didn't understand the question – Bozho Nov 16 '12 at 08:17
  • 3
    [From the doc](http://docs.oracle.com/javase/8/docs/api/java/util/Properties.html#load-java.io.Reader-): "**The key contains** all of the characters in the line starting with the first non-white space character and **up to, but not including, the first unescaped '=', ':', or white space character** other than a line terminator." So the space is documented as a delimiter, so I don't understand your statement "the delimiter should be `=`, not space.". The spec says space is a valid delimiter, so why "should" it be `=`? – Olivier Grégoire Aug 30 '17 at 15:18
4

I assume by "properties", you mean a Java property file (as written/read by java.util.Properties).

Then, as you write yourself,

foo bar = barefoot

must indeed be interpreted as

key: foo
value: bar = barefoot

There's no way to configure this using the built-in Properties class. You must either manipulate your input (escape the whitespace, change it to _ and back...), or write your own parser. Writing your own parser is probably better, as obviously your input isn't really a Java properties file to begin with :-).

bluish
  • 26,356
  • 27
  • 122
  • 180
sleske
  • 81,358
  • 34
  • 189
  • 227
  • 3
    +1 "not really a Java properties file to begin with". People see "key=value" and assume it's a properties file. They forget that there are quite a lot of rules around properties file, and if your input doesn't follow **all** of them, then it's not a properties file. Another example: Java properties use Latin1 (a.k.a ISO-8859-1) encoding by default and support Unicode escapes. – Joachim Sauer Jan 21 '10 at 10:01
  • Writing your own parser would need to take care of comments block in .properties too. – Om Sao Jul 04 '17 at 09:16
  • @OmSao: True. That nicely illustrates the problem that it's important to make sure you understand exactly what the file can or cannot contain. – sleske Jul 05 '17 at 04:55
0
keyValuePair = keyValuePair.substring(0,indexOf("=")).replaceAll("\\s+") + 
               keyValuePair.substring(indexOf("="));  
Yuriy N.
  • 4,936
  • 2
  • 38
  • 31