2016-09-16 57 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?)'的东西,它会找到零个或一个空格字符。 –