2016-09-16 82 views
1

我怎樣才能匹配一個字符串,但容忍模式中的變量levensthe距離?如何preg匹配PHP中的levenshtein距離的字符串

$string = 'i eat apples and oranges all day long'; 
$find = 'and orangis'; 
$distance = 1; 
$matches = pregMatch_withLevensthein($find, $distance, $string); 

這將返回'和橙子';

+0

這個問題已經在這裏找到答案:http://stackoverflow.com/questions/29781719/method-for-comparing-strings-in-php – rak007

+0

礦是不同的,因爲我想找到一個或兩個詞在一本書中,並且讓這些單詞稍微拼錯。這個問題是萊文斯坦距離的問題。如果我在我的例子中使用了levenshtein距離,它將不會返回「和橙子」。我需要檢查字符串是否包含「and orangis」或者與1個字符相同的字符串錯誤。隨着字符串變大,我會增加levenshtein距離。 –

+0

你需要將你的$ find變量轉換成一個類似的正則表達式,然後使用levensthein比較的所有匹配。如果它只是文本,應該很容易做到。你想要什麼功能返回,一場比賽還是所有的比賽? –

回答

2

通過將搜索字符串轉換爲正則表達式,我們可以匹配模式。然後我們使用該正則表達式進行搜索並與levenshtein進行比較。如果它匹配邊界,我們可以返回值。

$string = 'i eat apples and oranges all day long'; 
$find = 'and orangis'; 
$distance = 1; 
$matches = preg_match_levensthein($find, $distance, $string); 
var_dump($matches); 

function preg_match_levensthein($find, $distance, $string) 
{ 
    $found = array(); 

    // Covert find into regex 
    $parts = explode(' ', $find); 
    $regexes = array(); 
    foreach ($parts as $part) { 
     $regexes[] = '[a-z0-9]{' . strlen($part) . '}'; 
    } 
    $regexp = '#' . implode('\s', $regexes) . '#i'; 

    // Find all matches 
    preg_match_all($regexp, $string, $matches); 

    foreach ($matches as $match) { 
     // Check levenshtein distance and add to the found if within bounds 
     if (levenshtein($match[0], $find) <= $distance) { 
      $found[] = $match[0]; 
     } 
    } 

    // return found 
    return $found; 
} 
+0

這實際上回答了問題,所以我接受它。謝謝Chappell。不幸的是,它不適用於像「andoranges」這樣的東西:( –

+0

)如果你將implode改成類似'(\ s?)'的東西,它會找到零個或一個空格字符。 –