正则表达式基于和/或在搜索概念中打破字符串

时间:2014-04-29 22:04:24

标签: php regex

您好我正在尝试创建正则表达式,我遇到了问题。

基本上这就是我所拥有的:

(.+?)(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
                )
        )
)

非常感谢任何帮助!

2 个答案:

答案 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
                )

        )

)

Online php demo Online regex demo

答案 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
                )

        )

)