views:

196

answers:

3

I have a string like so:

option_alpha="value" option_beta="some other value" option_gamma="X" ...etc.

I'm using this to parse them into name & value pairs:

preg_match_all("/([a-z0-9_]+)\s*=\s*[\"\'](.+?)[\"\']/is", $var_string, $matches)

Which works fine, unless it encounters an empty attribute value:

option_alpha="value" option_beta="" option_gamma="X"

What have I done wrong in my regex?

A: 
[\"\'](.+?)[\"\']

should be

[\"\'](.*?)[\"\']

* instead of +. The first means there can be zero to whatever occurrences of the previous expression (so it can be omitted, that is what you need). The latter means, there has to be at least one.

Felix Kling
A: 

I think you want to change the very middle of your expression from (.+?) to (.*?). That makes it a non-greedy match on any character (including no characters), instead of a non-greedy match on at least one character.

preg_match_all("/([a-z0-9_]+)\s*=\s*[\"\'](.*?)[\"\']/is",$var_string,$matches);
zombat
A: 

The other answers here are right in that you need to change the middle of the expression, but I would change it to [^\"\']* which means "any character that is not a ", 0 or more times. This ensures the greediness doesn't match more than it is supposed to and allows for empty "".

your expression becomes
"/([a-z0-9_]+)\s*=\s*[\"\'][^\"\']*[\"\']/is"

note you can change the [a-z0-9_] to [\w_] which would also for upper case characters.

pocketfullofcheese