所有单词序列的正则表达式[关闭]

Using PHP, I want find all strings including list of words in the same order:

$searchable = array('cat', 'fruit', 'new');

And this strings are match:

'my cat is a Fruit of new';
'cat fruit new';

And this aren't match:

'Cat is my new fruit'
'Cat fruit'

Could you help me?

Simply use a pattern like this:

/cat.*fruit.*new/iu

If you need to automatically generate that pattern, try something like this:

$searchable = array('cat', 'fruit', 'new');
$pattern = '/' . implode('.*', 
    array_map(function($s) {
        return preg_quote($s, '/');
    }, $searchable)) . '/iu'; // '/cat.*fruit.*new/iu'

And for fun, here's a non-regex solution:

function matches_sequence($str, $seq) {
    for ($i = $c = 0; $i < count($seq); $i++)
    {
        $c = mb_stripos($str, $seq[$i], $c);
        if ($c === false) {
            return false;
        } else {
            $c += strlen($seq[$i]);
        }
    }
    return true;
}

$searchable = array('cat', 'fruit', 'new');
matches_sequence('my cat is a Fruit of new', $searchable); // true
matches_sequence('Cat is my new fruit', $searchable);      // false

As a non-regex solution, you can use stripos() .

function find_match($str, $searchable){
    $pos_arr = Array();
    foreach($searchable as $s){
        $pos = stripos($str, $s);
        if(
            (count($pos_arr) == 0) ||
            ($pos_arr[count($pos_arr)-1] < $pos) &&
            ($pos !== false)
        ){
            $pos_arr[] = $pos;
        }else{
            return false;
        }
    }
    return true;
}

The basic logic is, find the position of the searchable term one by one and store their index in $pos_arr. If the last entry has an index value greater than the present match, then return false.

Demo -

$searchable = array('cat', 'fruit', 'new');
$strings =  Array(
                    "my cat is a Fruit of new",
                    'cat fruit new',
                    'Cat is my new fruit',
                    'Cat fruit'
            );
foreach($strings as $str){
    print_r($str);
    var_dump(find_match($str, $searchable));
    print_r("<br />");
}
/*
    OUTPUT-
    my cat is a Fruit of new
    boolean true

    cat fruit new
    boolean true

    Cat is my new fruit
    boolean false

    Cat fruit
    boolean false
*/