2011-11-24 14 views
0

我需要構建一個正則表達式來查找輸入字符串中所有字符的出現。例如,如果用戶輸入「equ」作爲搜索參數,「queen」和「obsequious」將匹配,但是「qadaffi」和「tour」和「quail」不會。PHP或正則表達式:字符串匹配搜索模式中的所有字符

很顯然,我正在嘗試基本/ [等] /模式,它正在尋找「至少一個」。

如果有一個基本的PHP函數可以做到這一點,而沒有正則表達式,那麼這是可以接受的。但傷心。

+0

爲什麼equ應該匹配女王?因爲女王包含e和q和u? –

回答

3

/[equ]/是一個字符類,這意味着它只匹配一個字符。改爲嘗試/.*equ.*/。我沒有使用php匹配函數,所以.*可能是不必要的。

編輯:顯然他們肯定是不必要的,所以只需使用/equ/

+2

你是對的,他們是不必要的。 –

+0

假設一個字符串與兩個字符串匹配,'/.* equ。* /'和'/ equ /'之間的唯一區別是第一個默認情況下會貪婪地匹配整個字符串,而第二個只會匹配第一個字符串' 「EQU」'。如果只需要檢查子字符串,那麼是的,通配符是不必要的。 – BoltClock

0

可能是一個正則表達式不是這個工作的工具。不是一個PHP專家,但通過每個必需的字符循環檢查它存在於對象字符串中。

否則,使用正則表達式達到同樣的效果,但其緩慢而矯枉過正:

/^(?=.*e)(?=.*q)(?=.*u)/

2

是啊,一致認爲,簡單的for循環將是你的情況更爲有效。

假設$query = "que";$input = "queen";或其他任何東西:

$matched = true; 
$len = strlen($query); // or mb_strlen($query) if you have multibyte string in input 
for ($i = 0; $i < $len; $i++){ 
    if (!strstr($input, $query[$i])){ 
     $matched = false; 
     break; 
    } 
} 

非常原始的循環開始。

2

@sln @jancha

我已經實現了一個定時器來測量速度。奇怪的是,我發現正則表達式比我的代碼中的循環更快。這是正確的嗎?

$haystack = "Obsequious"; 
$needle = array('e','q','u'); 
$regex = "/^(?=.*e)(?=.*q)(?=.*u)/"; 

function trial(){ 
    GLOBAL $haystack; 
    GLOBAL $needle; 
    foreach ($needle as $n) { 
     if (!strpos($haystack, $n)) return false; 
    } 
    return true; 
} 

function trial2(){ 
    GLOBAL $haystack; 
    GLOBAL $regex; 
    if (preg_match($regex, $haystack)) { 
     return true; 
    } 
    return false; 
} 

print time_trial("trial"); 
print time_trial("trial2"); 

function time_trial($function, $iterations=100000){ 
    $before = microtime(true); 
    for ($i=0 ; $i<$iterations ; $i++) { 
     call_user_func($function); 
    } 
    $after = microtime(true); 
    $total = round($after-$before, 4); 
    return "Executed timed trial '$function' // $iterations iterations // $total seconds<br />\n"; 
} 
+0

你是否試過不符合標準的單詞?當我將測試詞更改爲「supercalifragilisticexpialidocious」時,正則表達式測試比其他測試詞要長約75%。這正是正則表達式因緩慢而得名的原因:失敗的比賽可能比成功的比賽要長得多 - 在某些情況下無限長。 –

+0

@Alan Moore這非常有道理。感謝您指出。所以取決於*實際內容,速度會有所不同。在某些情況下,正則表達式可能會更好,但在其他情況下,它可能不會。 – skibulk

+0

它也取決於正則表達式。這個 - '/^[^ equ] *(?:(?> e()| q()| u())[^ equ] *)* $ \ 1 \ 2 \ 3 /' - 非匹配案例中的'strpos'解決方案,匹配時* * *更好。這是因爲它只會讓輸入一次通過,並且它永遠不會回溯。不幸的是,消除正則表達式中的皺紋往往會對其外觀產生相反的影響。 ;) –