所有单词序列的正则表达式

时间:2014-02-23 14:50:35

标签: php regex string preg-match

使用PHP,我希望找到所有字符串,包括相同顺序的单词列表:

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

这个字符串匹配:

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

这不匹配:

'Cat is my new fruit'
'Cat fruit'

你能帮帮我吗?

2 个答案:

答案 0 :(得分:2)

只需使用这样的模式:

/cat.*fruit.*new/iu

如果您需要自动生成该模式,请尝试以下操作:

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

为了好玩,这是一个非正则表达式的解决方案:

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

答案 1 :(得分:0)

作为非正则表达式解决方案,您可以使用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;
}

基本逻辑是,逐个找到可搜索术语的位置,并将其索引存储在$pos_arr中。如果最后一个条目的索引值大于当前匹配,则返回false。

演示 -

$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
*/