您好我正在尝试创建正则表达式,我遇到了问题。
基本上这就是我所拥有的:
(.+?)(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
)
)
)
非常感谢任何帮助!
答案 0 :(得分:3)
这是一个递归函数,它也使用递归正则表达式,让我们递归!!!
$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
)
)
)
答案 1 :(得分:2)
试试这个,但我在PHP中使用了explode()方法,而不是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
)
)
)