$re = '/(?<command>add|do)(?=(?:.*?name\/"(?<taskName>.+?)"))(?=(?:.*?startDate\/"(?<startDate>.+?)")?)(?=(?:.*?endDate\/"(?<endDate>.+?)")?)(?=(?:.*\btags\/(?<tags>\w+(?:,\w+)*)?\b)?).*/';
$str = 'add name/"buy milk" startDate/"1110110000" endDate/"0812000000" tags/buy,shopping
add name/"buy milk" startDate/"today omg" endDate/"0812000000" tags/buy,shopping
add name/"buy milk" startDate/"today omg" tags/buy,shopping endDate/"0812000000"
add name/"buy milk" tags/buy,shopping startDate/"today omg" endDate/"0812000000"
add name/"buy milk" endDate/"0812000000" tags/buy,shopping startDate/"today omg"
add name/"buy milk" endDate/"0812000000" startDate/"today omg"
add name/"buy milk" endDate/"0812000000" tags/buy,shopping
add endDate/"0812000000" tags/buy,shopping name/"buy milk"
add endDate/"0812000000" name/"buy milk" tags/buy,shopping
do name/"buy milk"
do "buy milk" on/0812 tag/buy,shopping at/1000
do tag/buy,shopping on/0812 at/1000 "asdasd"
do tag/buy,shopping on/0812 "asdasd" at/1000
do at/1000 "buy milk"
do on/2100 "buy milk"
do at/1000 on/2100 "buy milk"
add at/1000 tag/omg "buy milk"
add on/2100 tag/omg "buy milk"
//floating task
do "buy milk"
on/2100 do "buy milk" at/1000 at/2100
';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for PHP, please visit: http://php.net/manual/en/ref.pcre.php