2013-05-13 84 views
13

PHP中的任何函數都檢查兩個字符串的相似度百分比嗎?如何檢查PHP中兩個字符串的部分相似度

,比如我有:

$string1="Hello how are you doing" 
$string2= " hi, how are you" 

function($string1, $string2)將返回我真因爲詞「如何」,「是」,「你」是存在於行。

甚至更​​好,回報我60%的相似性,因爲「如何」,「是」,「你」是$string1的3/5。

PHP中有哪些函數可以實現呢?

+3

通過了解雖然, 「相似」 可能意味着不同的事情。 – 2013-05-13 11:18:02

+1

請定義「相似性」。它與單個字符,單詞,還是短語有關?不要認爲'similar_text'會完成這項工作。 – enenen 2013-05-13 11:18:44

+1

similar_text函數做類似的事情,但閱讀http://stackoverflow.com/questions/14136349/how-does-similar-text-work,看看它是如何工作的。它可能不會達到你的期望。如果你想要匹配單詞的百分比,我會建議一個自定義的方法,使用某種形式的爆炸清理字符串。 – 2013-05-13 11:19:34

回答

8

正如其他答案已經說過,你可以使用similar_text。 這裏的演示:

$string1="Hello how are you doing" ; 
$string2= " hi, how are you"; 

echo similar_text($string1, $string2, $perc); //12 

echo $perc; //61.538461538462 

將返回12,並且將設置在$ PERC相似的百分比,你提出的要求。

+1

@Alex不需要使用PHP_EOL。 – 2013-05-13 11:55:57

+0

我剛剛使用EOL作爲回聲,所以結果格式很好,並且可讀。但是你是對的,它不需要代碼。 – 2013-05-13 11:57:16

25

由於這是一個很好的問題,我把一些精力投入到它:

<?php 
$string1="Hello how are you doing"; 
$string2= " hi, how are you"; 

echo 'Compare result: ' . compareStrings($string1, $string2) . '%'; 
//60% 


function compareStrings($s1, $s2) { 
    //one is empty, so no result 
    if (strlen($s1)==0 || strlen($s2)==0) { 
     return 0; 
    } 

    //replace none alphanumeric charactors 
    //i left - in case its used to combine words 
    $s1clean = preg_replace("/[^A-Za-z0-9-]/", ' ', $s1); 
    $s2clean = preg_replace("/[^A-Za-z0-9-]/", ' ', $s2); 

    //remove double spaces 
    while (strpos($s1clean, " ")!==false) { 
     $s1clean = str_replace(" ", " ", $s1clean); 
    } 
    while (strpos($s2clean, " ")!==false) { 
     $s2clean = str_replace(" ", " ", $s2clean); 
    } 

    //create arrays 
    $ar1 = explode(" ",$s1clean); 
    $ar2 = explode(" ",$s2clean); 
    $l1 = count($ar1); 
    $l2 = count($ar2); 

    //flip the arrays if needed so ar1 is always largest. 
    if ($l2>$l1) { 
     $t = $ar2; 
     $ar2 = $ar1; 
     $ar1 = $t; 
    } 

    //flip array 2, to make the words the keys 
    $ar2 = array_flip($ar2); 


    $maxwords = max($l1, $l2); 
    $matches = 0; 

    //find matching words 
    foreach($ar1 as $word) { 
     if (array_key_exists($word, $ar2)) 
      $matches++; 
    } 

    return ($matches/$maxwords) * 100;  
} 
?> 
+7

最後一個答案沒有無用(在本例中)'similar_text'。 +1 – enenen 2013-05-13 11:49:16

+1

哇!感謝您的傑出答案!唯一的問題是我使用不同語言的字符串。如日文,西班牙文,俄文。 還有另一種方法可以使它更有趣和複雜。例如,如果單詞以相同的順序出現,您想給它額外的相似點。像「你好,你好嗎」是好的,但「你好,你怎麼樣」我不太好。 – 2013-05-13 12:27:23

+0

另外,similar_text可以使錯誤更具說服力。例如,如果我寫「他在街上行走」和「他在街上行走」,它仍然可以。 – 2013-05-13 12:33:43

0

確定這裏是我的功能,使得它更有趣。

我在檢查字符串的大致相似性。

這是我使用的標準。

  1. 的字的順序是重要的
  2. 的話可以具有相似性的85%。

實施例:

$string1 = "How much will it cost to me" (string in vocabulary) 
$string2 = "How much does costs it " //("costs" instead "cost" -is a mistake) (user input); 

算法: 1)檢查字的相似性,並創建清潔字符串與「右」的單詞(在它出現在詞彙中的順序)。 輸出:「花多少錢」 2)用「正確的單詞」創建乾淨的字符串,以便它出現在用戶輸入中。 輸出:「多少成本」 3)比較兩個輸出 - 如果不相同 - 返回否,否則如果相同返回是。

error_reporting(E_ALL); 
ini_set('display_errors', true); 

$string1="сколько это стоит ваще" ; 
$string2= "сколько будет стоить это будет мне"; 

if(compareStrings($string1, $string2)) { 
echo "yes";  
} else { 
    echo 'no'; 
} 
//echo compareStrings($string1, $string2); 

function compareStrings($s1, $s2) { 

    if (strlen($s1)==0 || strlen($s2)==0) { 
     return 0; 
    } 

    while (strpos($s1, " ")!==false) { 
     $s1 = str_replace(" ", " ", $s1); 
    } 
    while (strpos($s2, " ")!==false) { 
     $s2 = str_replace(" ", " ", $s2); 
    } 

    $ar1 = explode(" ",$s1); 
    $ar2 = explode(" ",$s2); 
    // $array1 = array_flip($ar1); 
    // $array2 = array_flip($ar2); 
    $l1 = count($ar1); 
    $l2 = count($ar2); 

$meaning=""; 
    $rightorder=""; 
    $compare=0; 
    for ($i=0;$i<$l1;$i++) { 


     for ($j=0;$j<$l2;$j++) { 

      $compare = (similar_text($ar1[$i],$ar2[$j],$percent)) ; 
      // echo $compare; 
if ($percent>=85) { 
    $meaning=$meaning." ".$ar1[$i]; 
    $rightorder=$rightorder." ".$ar1[$j]; 
    $compare=0; 
} 

     } 


    } 
    //print_r($rightorder); 
if ($rightorder==$meaning) { 
    return true; 
} else { 
    return false; 
} 

} 

我很想聽聽您的意見和建議如何改進它

+0

很久以前,只是讀了這個答案。如果輸入兩個完全不同的字符串,它將返回true,因爲$ rightorder和$ meaning都保留一個空字符串。 – 2013-09-16 20:45:34

3

除了亞歷克斯Siri的答案,並按照下面的文章:

http://docstore.mik.ua/orelly/webprog/php/ch04_06.htm

PHP提供了一些功能讓您測試兩個字符串是否大致相等:

$string1="Hello how are you doing" ; 
$string2= " hi, how are you"; 

SOUNDEX

if (soundex($string1) == soundex($string2)) { 

    echo "similar"; 

} else { 

    echo "not similar"; 

} 

音位

if (metaphone($string1) == metaphone($string2)) { 

    echo "similar"; 

} else { 

    echo "not similar"; 

} 

類似的文本

$similarity = similar_text($string1, $string2); 

的Levenshtein

$similarity = levenshtein($string1, $string2); 
相關問題