Reputation: 195
I have a string of the following format:
xxx xxx xxx xxx
Now each part can be any of these values: abc, "abc", (abc), NIL
where abc is a string which may also have spaces, parentheses, quotes.
Example string:
TEXT "PLAIN" ("NAME" "file(1).txt") NIL
What is the best way to parse such a string into an array? i.e.
array[0] = TEXT
array[1] = "PLAIN"
array[2] = ("NAME" "file(1).txt")
array[3] = NIL
Upvotes: 0
Views: 472
Reputation: 15616
This regular expression will help you:
$result=array();
$subject = 'TEXT "PLAIN" (string with spaces) "string with other spaces" ("NAME" "file(1).txt") NIL';
$regex = '
/"([^"])+" # Match quote, followed by multiple non-quotes, ended by a quote.
|(\([\w ]+\)) # Or match multiple words and spaces between parentheses
|\(((?=")([^)]|(?>"|.))+)\) # Or Match text between parentheses, ignore ending parenthese if inside a quote
|\w+ # Or match single words
/x';
preg_match_all($regex, $subject, $result, PREG_PATTERN_ORDER);
$result = $result[0];
print_r($result);
print_r($result);
Test String :
TEXT "PLAIN" (string with spaces) "string with other spaces" ("NAME" "file(1).txt") NIL
Result :
Array
(
[0] => TEXT
[1] => "PLAIN"
[2] => (string with spaces)
[3] => "string with other spaces"
[4] => ("NAME" "file(1).txt")
[5] => NIL
)
Upvotes: 1
Reputation: 4439
Try this:
$input = 'TEXT "PLAIN" ("NAME" "file(1).txt") NIL';
$output = array();
$open = 0;
$parts = explode(' ', $input);
for ($i = $j = 0; $i < count($parts); $i++) {
$open += substr_count($parts[$i], '(');
$open -= substr_count($parts[$i], ')');
$output[$j] .= $parts[$i];
if ($open == 0) {
$j++;
}
}
var_dump($output);
What I do is simple : exploding the string in parts by cutting on spaces, then determining if we are inside parathesis or not to re-assemble parts when needed.
Upvotes: 0