2014-02-23 26 views
0

使用PHP,我想找到的所有字符串包括在同一順序的單詞列表:正則表達式的所有單詞序列

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

而這個字符串匹配:

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

這不匹配:

'Cat is my new fruit' 
'Cat fruit' 

你能幫幫我嗎?

+0

主要問題是在斯拉夫語:我試圖找到西里爾字符串匹配,而忘記了'u'修改。這個工作完美的'/貓。*水果。*新/ iu'(原始模式是'/кот。*фрукт。*новый/ iu') –

回答

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 
+0

在我的情況修飾符'u'模式解決了我的問題,Danke! –

+0

@IlyaKrigouzov很高興我能幫到你。爲了完整性,我更新了unicode支持的答案。 –

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