[ACCEPTED]-How can I find the Largest Common Substring between two strings in PHP?-spam-prevention

Accepted answer
Score: 10

The similar_text function may be what you want.

This 3 calculates the similarity between two strings. Returns 2 the number of matching chars in both strings

You 1 may also want to look at levenshtein

Score: 7

Especially since my application of this 5 is to search a database of email and look 4 for spam (i.e. similar emails sent by the 3 same person).

I think you should be looking 2 at Bayesian spam inference algorithms, not 1 necessarily longest common substring.

http://www.devshed.com/c/a/PHP/Implement-Bayesian-inference-using-PHP-Part-1/

Score: 6

I've just wrote a function the finds the 2 longest sub string in str1 that exists in 1 str2

public static function getLongestMatchingSubstring($str1, $str2)
{
    $len_1 = strlen($str1);
    $longest = '';
    for($i = 0; $i < $len_1; $i++){
        for($j = $len_1 - $i; $j > 0; $j--){
            $sub = substr($str1, $i, $j);
            if (strpos($str2, $sub) !== false && strlen($sub) > strlen($longest)){
                $longest = $sub;
                break;
            }
        }
    }
    return $longest;
}
Score: 4

Late to this party, but here is a way to 4 find the largest common substring in an 3 array of strings:

Example:

$array = array(
    'PTT757LP4',
    'PTT757A',
    'PCT757B',
    'PCT757LP4EV'
);
echo longest_common_substring($array); // => T757

The function:

function longest_common_substring($words) {
    $words = array_map('strtolower', array_map('trim', $words));
    $sort_by_strlen = create_function('$a, $b', 'if (strlen($a) == strlen($b)) { return strcmp($a, $b); } return (strlen($a) < strlen($b)) ? -1 : 1;');
    usort($words, $sort_by_strlen);
    // We have to assume that each string has something in common with the first
    // string (post sort), we just need to figure out what the longest common
    // string is. If any string DOES NOT have something in common with the first
    // string, return false.
    $longest_common_substring = array();
    $shortest_string = str_split(array_shift($words));

    while (sizeof($shortest_string)) {
        array_unshift($longest_common_substring, '');
        foreach ($shortest_string as $ci => $char) {
            foreach ($words as $wi => $word) {
                if (!strstr($word, $longest_common_substring[0] . $char)) {
                    // No match
                    break 2;
                } // if
            } // foreach
            // we found the current char in each word, so add it to the first longest_common_substring element,
            // then start checking again using the next char as well
            $longest_common_substring[0].= $char;
        } // foreach
        // We've finished looping through the entire shortest_string.
        // Remove the first char and start all over. Do this until there are no more
        // chars to search on.
        array_shift($shortest_string);
    }
    // If we made it here then we've run through everything
    usort($longest_common_substring, $sort_by_strlen);
    return array_pop($longest_common_substring);
}

I 2 have written this up a little bit on my 1 blog:

Score: 3

I have since found a relevant wikipedia article. It is not a NP complete 6 problem, it can be done in O(mn) time using 5 a dynamic programming algorithm.

In PHP I 4 found the similar_text function very useful. Here's 3 a code sample to retrieve a series of text 2 emails and loop through them and find ones 1 that are 90% similar to each other. Note: Something like this is NOT scalable:

<?php
// Gather all messages by a user into two identical associative arrays
$getMsgsRes = mysql_query(SELECT * FROM email_messages WHERE from = '$someUserID');
while($msgInfo = mysql_fetch_assoc($getMsgsRes))
{
    $msgsInfo1[] = $msgInfo;
    $msgsInfo2[] = $msgInfo;
}

// Loop over msgs and compare each one to every other
foreach ($msgsInfo1 as $msg1)
    foreach ($msgsInfo2 as $msg2)
        similar_text($msg1['msgTxt'],$msg2['msgTxt'],$similarity_pst);
        if ($similarity_pst > 90)
            echo "{$msg1['msgID']} is ${similarity_pst}% to {$msg2['msgID']}\n";
?>
Score: 1

Please have a look at Algorithm implementation/Strings/Longest common substring on Wikibooks. I haven't 3 tested the PHP implementation but it seems 2 to match the general algorithm on the Wikipedia 1 page.

More Related questions