PHP에서 두 문자열의 차이점을 강조
PHP에서 두 문자열의 차이점을 강조 표시하는 가장 쉬운 방법은 무엇입니까?
새 텍스트가 녹색이고 제거 된 텍스트가 빨간색 인 스택 오버플로 편집 기록 페이지의 줄을 따라 생각하고 있습니다. 미리 작성된 함수 나 클래스가 있으면 이상적입니다.
PHP Horde_Text_Diff를 사용할 수 있습니다 패키지를 . 그것은 당신의 요구에 적합하며, 꽤 커스터마이징이 가능합니다.
또한 GPL에 따라 라이센스가 부여되어 있으므로 즐기십시오!
하나의 문자열을 다른 문자열로 변환하기 위해 가장 적은 수의 편집을 계산하기 위해 클래스를 작성했습니다.
http://www.raymondhill.net/finediff/
diff의 HTML 버전을 렌더링하는 정적 함수가 있습니다.
그것은 첫 번째 버전이며 개선 될 가능성이 있지만 지금은 잘 작동하므로 누군가가 필요로하는 것처럼 컴팩트 한 diff를 효율적으로 생성 해야하는 경우에 대비하여 버리고 있습니다.
편집 : 그것은 지금 Github에 있습니다 : https://github.com/gorhill/PHP-FineDiff
강력한 라이브러리를 원한다면 Text_Diff (PEAR 패키지)가 꽤 좋아 보입니다. 꽤 멋진 기능이 있습니다.
이것은 또한 좋은 것입니다, http://paulbutler.org/archives/a-simple-diff-algorithm-in-php/
문제를 해결하는 것은 생각만큼 간단하지 않으며 문제를 파악하기 전에 약 1 년 동안 문제가 발생했습니다. 18 줄의 코드로 PHP로 알고리즘을 작성할 수있었습니다. diff를 수행하는 가장 효율적인 방법은 아니지만 이해하기 가장 쉬운 방법 일 것입니다.
두 문자열에 공통적 인 가장 긴 단어 시퀀스를 찾고 하위 문자열에 공통된 단어가 없을 때까지 나머지 문자열의 가장 긴 시퀀스를 재귀 적으로 찾습니다. 이 시점에서 나머지 새 단어를 삽입으로, 나머지 오래된 단어를 삭제로 추가합니다.
여기에서 소스를 다운로드 할 수 있습니다 : PHP SimpleDiff ...
다음은 두 배열을 비교하는 데 사용할 수있는 간단한 기능입니다. 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);
}
두 개의 배열을 생성합니다.
- values 배열 : diff에 나타나는 요소 목록.
- 마스크 배열 : 숫자를 포함합니다. 0 : 변경되지 않음, -1 : 제거됨, 1 : 추가됨.
배열을 문자로 채우면 인라인 차이를 계산하는 데 사용할 수 있습니다. 이제 차이점을 강조하기위한 단 한 단계 만 수행하십시오.
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;
}
예 :
echo diffline('StackOverflow', 'ServerFault')
출력합니다 :
S<del>tackO</del><ins>er</ins>ver<del>f</del><ins>Fau</ins>l<del>ow</del><ins>t</ins>
에스압정에버에프폴아야티
추가 사항 :
- The diff matrix requires (m+1)*(n+1) elements. So you can run into out of memory errors if you try to diff long sequences. In this case diff larger chunks (eg. lines) first, then diff their contents in a second pass.
- The algorithm can be improved if you trim the matching elements from the beginning and the end, then run the algorithm on the differing middle only. A latter (more bloated) version contains these modifications too.
There is also a PECL extension for xdiff:
In particular:
- xdiff_string_diff — Make unified diff of two strings
Example from 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;
}
I had terrible trouble with the both the PEAR-based and the simpler alternatives shown. So here's a solution that leverages the Unix diff command (obviously, you have to be on a Unix system or have a working Windows diff command for it to work). Choose your favourite temporary directory, and change the exceptions to return codes if you prefer.
/**
* @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);
}
}
This is the best one I've found.
http://code.stephenmorley.org/php/diff-implementation/
What you are looking for is a "diff algorithm". A quick google search led me to this solution. I did not test it, but maybe it will do what you need.
A php port of Neil Frasers diff_match_patch (Apache 2.0 licensed)
I would recommend looking at these awesome functions from PHP core:
similar_text — Calculate the similarity between two strings
http://www.php.net/manual/en/function.similar-text.php
levenshtein — Calculate Levenshtein distance between two strings
http://www.php.net/manual/en/function.levenshtein.php
soundex — Calculate the soundex key of a string
http://www.php.net/manual/en/function.soundex.php
metaphone — Calculate the metaphone key of a string
http://www.php.net/manual/en/function.metaphone.php
I came across this PHP diff class by Chris Boulton based on Python difflib which could be a good solution:
참고URL : https://stackoverflow.com/questions/321294/highlight-the-difference-between-two-strings-in-php
'IT' 카테고리의 다른 글
코드로 조각 태그를 설정하는 방법은 무엇입니까? (0) | 2020.06.28 |
---|---|
Java에서 String 클래스가 final로 선언 된 이유는 무엇입니까? (0) | 2020.06.28 |
Javascript에서 가속도계 / 자이로 스코프 데이터에 액세스하는 방법은 무엇입니까? (0) | 2020.06.28 |
파이썬에서 두 목록에 동일한 요소가 포함되어 있다고 주장하는 방법은 무엇입니까? (0) | 2020.06.28 |
ThreadStatic 속성은 어떻게 작동합니까? (0) | 2020.06.28 |