variable strings palabras contiene con comparar caracter cadena buscar php string diff word-diff

strings - php si contiene cadena



Resalta la diferencia entre dos cadenas en PHP (12)

Aquí hay una breve función que puede usar para diferenciar dos matrices. Implementa el algoritmo LCS :

function computeDiff($from, $to) { $diffValues = array(); $diffMask = array(); $dm = array(); $n1 = count($from); $n2 = count($to); for ($j = -1; $j < $n2; $j++) $dm[-1][$j] = 0; for ($i = -1; $i < $n1; $i++) $dm[$i][-1] = 0; for ($i = 0; $i < $n1; $i++) { for ($j = 0; $j < $n2; $j++) { if ($from[$i] == $to[$j]) { $ad = $dm[$i - 1][$j - 1]; $dm[$i][$j] = $ad + 1; } else { $a1 = $dm[$i - 1][$j]; $a2 = $dm[$i][$j - 1]; $dm[$i][$j] = max($a1, $a2); } } } $i = $n1 - 1; $j = $n2 - 1; while (($i > -1) || ($j > -1)) { if ($j > -1) { if ($dm[$i][$j - 1] == $dm[$i][$j]) { $diffValues[] = $to[$j]; $diffMask[] = 1; $j--; continue; } } if ($i > -1) { if ($dm[$i - 1][$j] == $dm[$i][$j]) { $diffValues[] = $from[$i]; $diffMask[] = -1; $i--; continue; } } { $diffValues[] = $from[$i]; $diffMask[] = 0; $i--; $j--; } } $diffValues = array_reverse($diffValues); $diffMask = array_reverse($diffMask); return array(''values'' => $diffValues, ''mask'' => $diffMask); }

Genera dos matrices:

  • array de valores: una lista de elementos tal como aparecen en el diff.
  • conjunto de máscara: contiene números. 0: sin cambios, -1: eliminado, 1: agregado.

Si llena una matriz con caracteres, se puede usar para calcular la diferencia en línea. Ahora solo un paso para resaltar las diferencias:

function diffline($line1, $line2) { $diff = computeDiff(str_split($line1), str_split($line2)); $diffval = $diff[''values'']; $diffmask = $diff[''mask'']; $n = count($diffval); $pmc = 0; $result = ''''; for ($i = 0; $i < $n; $i++) { $mc = $diffmask[$i]; if ($mc != $pmc) { switch ($pmc) { case -1: $result .= ''</del>''; break; case 1: $result .= ''</ins>''; break; } switch ($mc) { case -1: $result .= ''<del>''; break; case 1: $result .= ''<ins>''; break; } } $result .= $diffval[$i]; $pmc = $mc; } switch ($pmc) { case -1: $result .= ''</del>''; break; case 1: $result .= ''</ins>''; break; } return $result; }

P.ej.:

echo diffline(''StackOverflow'', ''ServerFault'')

Se producirá:

S<del>tackO</del><ins>er</ins>ver<del>f</del><ins>Fau</ins>l<del>ow</del><ins>t</ins>

S taco erver F Faul Ay t

Notas adicionales:

  • La matriz de diferencias requiere elementos (m + 1) * (n + 1). Por lo tanto, puede ejecutar errores sin memoria si intenta diferir secuencias largas. En este caso, difiera trozos más grandes (por ejemplo, líneas) primero, luego difunda su contenido en un segundo pase.
  • El algoritmo puede mejorarse si recorta los elementos coincidentes desde el principio y el final, luego ejecuta el algoritmo solo en el medio diferente. Una última versión (más inflada) contiene estas modificaciones también.

¿Cuál es la forma más fácil de resaltar la diferencia entre dos cadenas en PHP?

Estoy pensando en las líneas de la página del historial de edición de Stack Overflow, donde el texto nuevo está en verde y el texto eliminado en rojo. Si hay funciones o clases preescritas disponibles, sería ideal.


Esta es una buena, también http://paulbutler.org/archives/a-simple-diff-algorithm-in-php/

Resolver el problema no es tan simple como parece, y el problema me molestó durante aproximadamente un año antes de que me diera cuenta. Logré escribir mi algoritmo en PHP, en 18 líneas de código. No es la manera más eficiente de hacer una diferencia, pero es probablemente la más fácil de entender.

Funciona al encontrar la secuencia más larga de palabras comunes a ambas cadenas, y encontrar recursivamente las secuencias más largas de los restos de la cadena hasta que las subcadenas no tengan palabras en común. En este punto, agrega las palabras nuevas restantes como una inserción y las palabras antiguas restantes como una eliminación.

Puede descargar la fuente aquí: PHP SimpleDiff ...



Lo que estás buscando es un "algoritmo de diferencias". Una búsqueda rápida en Google me llevó a esta solución . No lo probé, pero tal vez hará lo que necesita.


Me encontré con esta clase PHP diff de Chris Boulton basada en Python difflib que podría ser una buena solución:

PHP Diff Lib


Puede usar el paquete PHP Horde_Text_Diff . Se adapta a tus necesidades, y es bastante personalizable también.

También tiene licencia bajo la GPL, así que ¡disfruta!


Si desea una biblioteca sólida, Text_Diff (un paquete PEAR) parece ser bastante bueno. Tiene algunas características muy interesantes.


Simplemente escribí una clase para calcular el número más pequeño (no se debe tomar literalmente) de ediciones para transformar una cadena en otra cadena:

http://www.raymondhill.net/finediff/

Tiene una función estática para representar una versión HTML de la diferencia.

Es una primera versión, y es probable que sea mejorada, pero funciona bien a partir de ahora, así que la estoy lanzando en caso de que alguien necesite generar un compact diff de manera eficiente, como lo necesitaba.

Editar: está en Github ahora: https://github.com/gorhill/PHP-FineDiff


También hay una extensión PECL para xdiff:

En particular:

Ejemplo de PHP Manual:

<?php $old_article = file_get_contents(''./old_article.txt''); $new_article = $_POST[''article'']; $diff = xdiff_string_diff($old_article, $new_article, 1); if (is_string($diff)) { echo "Differences between two articles:/n"; echo $diff; }


Tuve un problema terrible con las alternativas tanto basadas en PEAR como las más simples que se muestran. Así que aquí hay una solución que aprovecha el comando diff de Unix (obviamente, tienes que estar en un sistema Unix o tener un comando de Windows diff que funcione para que funcione). Elija su directorio temporal favorito y cambie las excepciones para devolver los códigos si lo prefiere.

/** * @brief Find the difference between two strings, lines assumed to be separated by "/n| * @param $new string The new string * @param $old string The old string * @return string Human-readable output as produced by the Unix diff command, * or "No changes" if the strings are the same. * @throws Exception */ public static function diff($new, $old) { $tempdir = ''/var/somewhere/tmp''; // Your favourite temporary directory $oldfile = tempnam($tempdir,''OLD''); $newfile = tempnam($tempdir,''NEW''); if (!@file_put_contents($oldfile,$old)) { throw new Exception(''diff failed to write temporary file: '' . print_r(error_get_last(),true)); } if (!@file_put_contents($newfile,$new)) { throw new Exception(''diff failed to write temporary file: '' . print_r(error_get_last(),true)); } $answer = array(); $cmd = "diff $newfile $oldfile"; exec($cmd, $answer, $retcode); unlink($newfile); unlink($oldfile); if ($retcode != 1) { throw new Exception(''diff failed with return code '' . $retcode); } if (empty($answer)) { return ''No changes''; } else { return implode("/n", $answer); } }


Yo recomendaría mirar estas funciones increíbles desde el núcleo de PHP:

similar_text - Calcula la similitud entre dos cadenas

http://www.php.net/manual/en/function.similar-text.php

levenshtein - Calcule la distancia Levenshtein entre dos cuerdas

http://www.php.net/manual/en/function.levenshtein.php

soundex - Calcula la clave soundex de una cadena

http://www.php.net/manual/en/function.soundex.php

metafonía: calcula la tecla de metafonía de una cadena

http://www.php.net/manual/en/function.metaphone.php