2013-05-13 15 views
13

Czy to jakaś funkcja w PHP sprawdza% podobieństwa dwóch łańcuchów?Jak sprawdzić częściowe podobieństwo dwóch łańcuchów w PHP

Na przykład mam:

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

i function($string1, $string2) zwróci mi prawdziwe, ponieważ słowa „jak”, „to”, „ty” są obecne w linii.

Albo jeszcze lepiej, zwróć mi 60% podobieństwa, ponieważ "jak", "jest", "ty" jest 3/5 z $string1.

Czy istnieje jakaś funkcja w PHP, która to robi?

+3

By jednak świadomi, że "podobne" może oznaczać różne rzeczy. –

+1

Proszę zdefiniować "podobieństwo". Czy jest to związane z pojedynczymi postaciami, słowami, frazami? Nie myśl, że "podobny_tekst" wykona pracę. – enenen

+1

Funkcja similar_text robi coś takiego, ale przeczytaj http://stackoverflow.com/questions/14136349/how-does-similar-text-work, aby zobaczyć, jak to działa. Może nie robić tego, czego się spodziewasz. Jeśli chcesz uzyskać procent pasujących słów, proponuję niestandardową metodę, używając jakiegoś rodzaju eksplodować w oczyszczonym ciągu. –

Odpowiedz

8

Jak już napisano już w innych odpowiedziach, można użyć parametru similar_text. Oto demonstracji:

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

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

echo $perc; //61.538461538462 

powróci 12 i będzie ustawiony w $ perc procent podobieństwa jak prosiłeś.

+1

@Alex nie trzeba używać PHP_EOL. –

+0

Właśnie użyłem EOL dla echa, więc formaty wyników są ładne i można je odczytać. Ale masz rację, to nie jest potrzebne dla kodu. –

25

Jak to miły pytanie, kładę trochę wysiłku w to:

<?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

Na koniec odpowiedź bez bezużytecznego (w tym przypadku) "podobnego_tekstu". +1 – enenen

+1

Wow! Dzięki za błyskotliwą odpowiedź! Jedynym problemem jest to, że używam ciągów w różnych językach. jak japoński, hiszpański, rosyjski. Istnieje jeszcze jeden sposób, aby uczynić go bardziej interesującym i skomplikowanym. Na przykład chcesz nadać mu dodatkowe punkty podobieństwa, jeśli słowa są w tej samej kolejności. jak "Cześć, jak się masz" jest ok, ale "Cześć, jak się masz", jestem mniej dobry. –

+0

Ponadto, podobnie_tekst może sprawić, że będzie bardziej wrażliwy na błędy. Na przykład, jeśli piszę "idzie na ulicę" i "idzie na ulicę", wszystko będzie w porządku. –

0

Ok tutaj jest moja funkcja, która sprawia, że ​​znacznie interesujący.

Sprawdzam podobieństwo ciągów.

Oto kryteria, których używam.

  1. Kolejność słów jest ważne
  2. Słowa mogą mieć 85% podobieństwa.

przykład:

$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); 

Algorytm: +1) Sprawdź podobieństwo słów i tworzyć czyste ciągi słów „prawo” (w takiej kolejności, że pojawiają się w słownictwo). WYJŚCIE: "ile to kosztuje" 2) utwórz czysty ciąg z "prawymi słowami", aby pojawił się w danych użytkownika. WYJŚCIE: "ile to kosztuje" 3) Porównaj dwa wyjścia - jeśli nie to samo - zwróć nie, w przeciwnym wypadku, jeśli ten sam zwrot tak.

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; 
} 

} 

i chcielibyśmy usłyszeć swoją opinię i sugestie, jak poprawić

+0

Dawno temu, ale po prostu przeczytaj tę odpowiedź.Jeśli wprowadzę dwa całkowicie różne ciągi, to zwrócą one true, ponieważ '$ rightorder' i' $ meaning' oba pozostają pustymi ciągami. –

3

Oprócz odpowiedzi Alex Siri i zgodnie z poniższym artykule:

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

PHP udostępnia kilka funkcji które pozwalają sprawdzić, czy dwa ciągi są w przybliżeniu równe:

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

SOUNDEX

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

    echo "similar"; 

} else { 

    echo "not similar"; 

} 

Metaphone

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

    echo "similar"; 

} else { 

    echo "not similar"; 

} 

podobny tekst

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

Levenshteina

$similarity = levenshtein($string1, $string2); 
Powiązane problemy