views:

165

answers:

4

I'm trying to create a method which takes a String parameter and then returns a two dimensional String array of parameter names and values.

protected final String[][] setParams (String parms) {
    String[][] params;
    int i = 0;
    Pattern p = Pattern.compile(NEED_REGEX_HERE);
    Matcher m = p.matcher(parms);

    params = String[m.groupCount()][2];

    while (m.find()) {
        params[i][0] = m.group(i).subString(0,m.group(i).indexOf('='));
        params[i][1] = m.group(i).subString(m.group(i).indexOf('='));
        i++;
    }

    return params;
}

Some examples of input would be (inside quotes):

"Name=Ryan;\;Name=John"
"Name=Ryan;Name=John"
"Name=Ryan"
"Name=Ryan;Index=1"

So a ";" is the list delimeter and the assignment operator "=" denotes a valid parameter ie. "\" is a throw away value. Basically I'm looking for a regex that will allow me to do this, or if someone can provide one, a more elegant solution.

A: 

There are enough gotchas in this that you're better off using a prewritten library (e.g. parsing "-h, --help, foo=bar" option forms, etc etc). There are lots of libraries built to do this. A quick search turned up a short list here.

If you really want to write it yourself, I'd just try to split each cmd-line option by the "=", with copious and friendly error messages for all the malformed commands you'll get.

Steve B.
You're really assuming too much about how much control I have over my input. I'm pulling these lines out of a file and am outputting to a csv conditionally based on what parameters are defined.
binarymelon
+1  A: 

Two splits should work for the given examples:

String[] keyValuePairs = line.split(";");
for (String keyValuePair:keyValuePairs) {
  if (isThrowAwayParameter(keyValuePair)) {
    handleThrowAwayParameter();
  } else {
    String[] keyAndValue = keyValuePair.split("=");
    String key = keyAndValue[0];
    String value = keyAndValue[1];
    handleKeyAndValue(key, value);
  }
}
Andreas_D
I don't know why I always try to over-complicate things. Thanks. This worked perfectly. I switched to a List of String arrays to handle the dynamic sizing, but thank you so much.
binarymelon
+2  A: 

In case you were still curious about the regex version (I know you have already marked an answer)... it would go something like this:

Pattern p = Pattern.compile( "(\\w+)=(\\w+);?" );
Matcher m = p.matcher( myString );
while( m.find() ) {
    System.out.println( "name[" + m.group(1) + "] = value[" + m.group(2) + "]" );
}

That presumes that the names and values are only made up of word characters (alphanumeric). The semi-colon with "optional" quantifier is actually unnecessary in this case since this will happily skip over things it doesn't understand.

PSpeed
A: 

If parameter names are unique you can use Properties class:

Properties p = new Properties();
p.load(new StringReader(parms.replaceAll(";", "\n")));
Lluis Martinez