Привет, Я пытаюсь создать выражение регулярных выражений, и я столкнулся с проблемами.
В основном это то, что у меня есть:
(.+?)(and|or)(.+?)
Что я ищу, например:
(user email ends with "@email.com" and user name is "John") or (user email ends with "@domain.com" and user name is "Bob")
И мой ожидаемый результат, который я хотел бы получить, это:
(user email ends with "@email.com" and user name is "John") (user email ends with "@domain.com" and user name is "Bob")
В принципе, OR будет разделяться на основе «()», который является необязательным, поэтому я могу иметь что-то вроде этого
user email ends with "@email.com" and user name is "John"
Который я ожидаю быть таким:
user email ends with "@email.com" user name is "John"
если мне нужно иметь более одного регулярного выражения, я найду с этим, Конечная цель – это что-то вроде этого:
Array ( [0] => Array ( [0] => user email ends with "@email.com" [1] => user name is "John" ) [1] => Array ( [0] => user email ends with "@domain.com" [1] => user name is "Bob" ) )
Если это что-то вроде этого
(user email ends with "@email.com" and user name is "John") or ((user email ends with "@domain.com" and user name is "Bob") or (user id is 5))
Тогда я ожидал бы что-то вроде этого
Array ( [0] => Array ( [0] => user email ends with "@email.com" [1] => user name is "John" ) [1] => Array ( [0] => user email ends with "@domain.com" [1] => user name is "Bob" [2] => Array ( [0] => user id is 5 ) ) )
Любая помощь будет высоко ценится!
Вот рекурсивная функция, которая также использует рекурсивное регулярное выражение, давайте рекурсивно !!!
$text = '(user email ends with "@email.com" and user name is "John") or ((user email ends with "@domain.com" and user name is "Bob") or (user id is 5))'; print_r(buildtree($text)); function buildtree($input){ $regex = <<<'regex' ~( # Group 1 \( # Opening bracket ( # Group 2 (?: # Non-capturing group [^()] # Match anything except opening or closing parentheses | # Or (?1) # Repeat Group 1 )* # Repeat the non-capturing group zero or more times ) # End of group 2 \) # Closing bracket )~x regex; // The x modifier is for this nice and fancy spacing/formatting $output = []; if(preg_match_all($regex, $input, $m)){ // If there is a match foreach($m[2] as $expression){ // We loop through it $output[] = buildtree($expression); // And build the tree, recursive !!! } return $output; }else{ // If there is no match, we just split return preg_split('~\s*(?:or|and)\s*~i', $input); } }
Вывод:
Array ( [0] => Array ( [0] => user email ends with "@email.com" [1] => user name is "John" ) [1] => Array ( [0] => Array ( [0] => user email ends with "@domain.com" [1] => user name is "Bob" ) [1] => Array ( [0] => user id is 5 ) ) )
Онлайн демоверсия php Online regex demo
Попробуйте это, но я использовал метод explode () в PHP, а не в Regex.
Вход должен иметь каждого пользователя в строке и без круглых скобок (вы можете изменить код для удаления скобок), но по крайней мере это концепция.
<?php $string = 'user email ends with "@domain.com" and user name is "Bob" or user id is 5 user email ends with "@domain.com" and user name is "Bob" or user id is 5'; echo"<pre>"; //final array $result = array(); //separate each line as element in an array $line = explode("\n",$string); //iterate through each line for($k=0; $k<count($line);$k++){ //find the and first and separate $and = explode("and",$line[$k]); $and_size = count($and); //find the or in each separted and for($i=0;$i<$and_size;$i++){ $or = explode("or",$and[$i]); //place found ors in a new subarray if(count($or) > 1){ $and[] = array(); $lastId = count($and)-1; for($j=1; $j<count($or);$j++){ $and[$lastId][] = $or[$j]; } } } $result[] = $and; } print_r($result);
Выход :
Array ( [0] => Array ( [0] => user email ends with "@domain.com" [1] => user name is "Bob" or user id is 5 [2] => Array ( [0] => user id is 5 ) ) [1] => Array ( [0] => user email ends with "@domain.com" [1] => user name is "Bob" or user id is 5 [2] => Array ( [0] => user id is 5 ) ) )