পিএইচপি-তে দুটি স্ট্রিংয়ের মধ্যে পার্থক্য হাইলাইট করুন


136

পিএইচপি-তে দুটি স্ট্রিংয়ের মধ্যে পার্থক্য হাইলাইট করার সহজতম উপায় কী?

আমি স্ট্যাক ওভারফ্লো সম্পাদনা ইতিহাস পৃষ্ঠার লাইন ধরে ভাবছি, যেখানে নতুন পাঠ্য সবুজ এবং মুছে ফেলা পাঠ্য লাল। যদি কোনও প্রাক-লিখিত ফাংশন বা ক্লাস উপলব্ধ থাকে তবে তা আদর্শ।

উত্তর:


42

আপনি পিএইচপি Horde_Text_Diff প্যাকেজটি ব্যবহার করতে সক্ষম হয়েছিলেন।

তবে এই প্যাকেজটি আর উপলব্ধ নেই।


1
লিঙ্কটি আর কাজ করে না। এটা কি এখন 2011 সালে অন্য কোন সমাধান? ;-) এটা সম্ভব ভালো যেতে পেতে আউটপুট tortoisesvn.tigris.org/images/TMerge2Diff.png
Glavić

3
সাইট চলে গেছে, তবে আর্কাইভ.আর.র সাইটটির একটি অনুলিপি রয়েছে: web.archive.org/web/20080506155528/http://software.zuavra.net/…
আর হিল

15
খুব খারাপ এটির জন্য পিয়ার দরকার। পিয়ার-নির্ভরতা স্তন্যপান।
রুডি

7
নতুন ওয়েবসাইট থেকে: "আপডেট করুন: ইনলাইন রেন্ডারার এখন টেক্সট_ডিফ পিয়ার প্যাকেজের একটি আদি অংশ। এখন আপনাকে এখানে উপস্থাপিত হ্যাক ব্যবহার করার দরকার নেই।" তাই এখনই টেক্সট_ডিফ ব্যবহার করুন।
মাদুর

11
জিপিএল ব্যবহারের জন্য কেবল নিখরচায় নয়। এটি আপনার মডিউল / প্রকল্পটিকেও জিপিএল হতে বাধ্য করে।
প্যারিস

76

একটি স্ট্রিংকে অন্য স্ট্রিংয়ে রূপান্তর করতে সংক্ষিপ্ত সংখ্যক সম্পাদনা গণনা করতে কেবল একটি ক্লাস লিখেছিলেন:

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

ডিফের এইচটিএমএল সংস্করণটি রেন্ডার করতে এটির একটি স্ট্যাটিক ফাংশন রয়েছে।

এটি প্রথম সংস্করণ, এবং সম্ভবত এটির উন্নতি হতে পারে, তবে এটি এখন ঠিক ঠিক কাজ করে, সুতরাং কারওর জন্য আমার প্রয়োজন মতো দক্ষতার সাথে একটি কমপ্যাক্ট ডিফারেন্ট তৈরির প্রয়োজন হলে আমি এটি সেখানে ফেলে দিচ্ছি।

সম্পাদনা করুন: এটি এখন গিথুবে রয়েছে: https://github.com/gorhill/PHP-FineDiff


3
মাল্টিবাইট সমর্থন পেতে আমি github.com/xrstf/PHP- ফাইনডিফে কাঁটাচামচ চেষ্টা করব !
activout.se

1
@R। হিল - আমার জন্যও খুব সুন্দর কাজ করে। এটি হ'ল বর্তমানের চেয়ে উত্তম উত্তর যা অবনমিত বলে মনে হচ্ছে।
ওঙ্কো দ্য সনে

কোন আপডেট? এটি বলে যে "টেক্সটস / ডিফএফপিপি" ফাইল অন্তর্ভুক্ত করতে ব্যর্থ হয়েছে এবং এটি জিপটিতে নেই।
SISYN

অ্যামেজিং! আমি উদাহরণ কোড সহ অনলাইন ডেমো বলতে চাই। নিখুঁত চর-স্তরের পার্থক্য। এইমাত্র! : হে আপনাকে ধন্যবাদ!
ফিলিপ ওভারটোনসিংগার রাইডলো

2
দেখে মনে হচ্ছে যে এখন গিথুব . com/ বিলিএনএট / পিএইচপি- ফাইনডিফ কাঁটাচটি সবচেয়ে এগিয়ে এবং এটি বিভিন্ন এনকোডিং সহ মাল্টিবাইটগুলিকে সমর্থন করে। github.com/xrstf/PHP-FineDiff @ activout.se 404ing হয়
Kangur

24

আপনি যদি একটি শক্তিশালী গ্রন্থাগার চান তবে পাঠ্য_ডিফ (একটি পিয়ার প্যাকেজ) দেখতে বেশ ভাল লাগছে। এর বেশ কয়েকটি দুর্দান্ত বৈশিষ্ট্য রয়েছে।


6
উপরে উল্লিখিত পিএইচপি ইনলাইন-ডিফ, ".. একটি পার্থক্য গণনা করার জন্য PEAR থেকে পাঠ্য_ডিফ ব্যবহার করুন"। :)
এমএন

লিঙ্কটি নষ্ট হয়ে গেছে। প্যাকেজটি সন্ধান করতে পারেন না। এটি ওয়ার্ডপ্রেসের সর্বশেষ সংস্করণ দ্বারা ব্যবহৃত একই ডিফ প্যাকেজ।
তুলসী মুসা

24

এটি একটি চমৎকার এক, হয় http://paulbutler.org/archives/a-simple-diff-algorithm-in-php/

সমস্যাটি সমাধান করা যতটা সহজ মনে হচ্ছে তত সহজ নয় এবং আমি এটি বের করার আগে সমস্যাটি প্রায় এক বছর ধরে আমাকে বিরক্ত করেছিল। আমি 18 লাইনের কোডে পিএইচপিতে আমার অ্যালগরিদম লিখতে সক্ষম হয়েছি। এটি কোনও আলাদা করার সবচেয়ে কার্যকর উপায় নয় তবে এটি বোঝার পক্ষে এটি সবচেয়ে সহজ।

এটি উভয় স্ট্রিংয়ে সাধারণ শব্দের দীর্ঘতম ক্রম সন্ধান করে এবং সাবস্ট্রিংগুলিতে কোনও শব্দের মিল না পাওয়া পর্যন্ত পুনরাবৃত্তভাবে স্ট্রিংয়ের অবশিষ্ট অংশগুলির দীর্ঘতম ক্রম সন্ধান করে কাজ করে। এই সময়ে এটি সন্নিবেশ হিসাবে অবশিষ্ট নতুন শব্দ এবং একটি মুছে ফেলা হিসাবে অবশিষ্ট পুরানো শব্দ যুক্ত করে adds

আপনি উত্সটি এখানে ডাউনলোড করতে পারেন: পিএইচপি সিম্পলডিফ ...


1
আমি এটি খুব দরকারী হিসাবে খুঁজে পেয়েছি! পিয়ার স্টাফের মতো জটিল নয়।
ডিজাগে

: এটা আমাকে একটি errror এখানে দেয়if($matrix[$oindex][$nindex] > $maxlen){ Undefined variable: maxlen
গতিশীল

ওকে সমাধান করার জন্য আপনি একটি কমমেট পোস্ট করেছেন। :) আপনি প্রাথমিক কোডে এডিট করবেন না কেন? যাইহোক ধন্যবাদ +1 ... হুম ভাল আপনি লেখক নন
গতিশীল

1
২০১০ সালের সর্বশেষ সংস্করণ হিসাবে প্রদর্শিত হচ্ছে তা এখানে: github.com/paulgb/simplediff/blob/master/simplediff.php
RSSk82

প্রকৃতপক্ষে, সরলতার জন্য +1
প্যারাগ তায়াগি

17

এখানে একটি সংক্ষিপ্ত ফাংশন আপনি দুটি অ্যারে আলাদা করতে ব্যবহার করতে পারেন। এটি এলসিএস অ্যালগরিদম প্রয়োগ করে :

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

এটি দুটি অ্যারে তৈরি করে:

  • মানসমূহের অ্যারে: উপাদানগুলির তালিকা যেমন তারা ভিন্ন হয়।
  • মাস্ক অ্যারে: সংখ্যা রয়েছে। 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> 

এসtackOerverFaulOwটি

অতিরিক্ত নোট:

  • ডিফ ম্যাট্রিক্সের জন্য (এম + 1) * (এন + 1) উপাদান প্রয়োজন। সুতরাং আপনি দীর্ঘ ক্রমগুলি পৃথক করার চেষ্টা করলে আপনি মেমরির ত্রুটিগুলি ছাপিয়ে যেতে পারেন। এক্ষেত্রে প্রথমে বৃহত্তর অংশগুলি (যেমন লাইনগুলি) আলাদা করুন, তারপরে তাদের পাসওয়ার্ডগুলি দ্বিতীয় পাসে আলাদা করুন।
  • আপনি যদি শুরু এবং শেষ থেকে মিলের উপাদানগুলি ছাঁটাই করেন তবে অ্যালগরিদমটি উন্নত হতে পারে তবে কেবলমাত্র ভিন্ন মিডিয়ায় অ্যালগরিদমটি চালান। একটি আধুনিক (আরও স্ফীত) সংস্করণ এই পরিবর্তন খুব ধারণ করে।

এটি সহজ, কার্যকর এবং ক্রস প্ল্যাটফর্ম; আমি এই কৌশলটি বিস্ফোরিত () দিয়ে বিভিন্ন সীমানায় (লাইন বা শব্দ) ব্যবহার করে যেখানে উপযুক্ত সেখানে ভিন্ন আউটপুট পেতে। খুব সুন্দর সমাধান, ধন্যবাদ!
চাচা কোড বানর

এটি বলেছেcomputeDiff is not found
ichimaru

@চিমাড়ু আপনি কি দুটি ফাংশন পেস্ট করেছেন?
কলমারিয়াস

@ কলমারিয়াস অন্য ফাংশনটি দেখেনি ... আমি দিব্যি! এটি এখন কাজ ধন্যবাদ!
ইছিমারু

ধন্যবাদ, গৃহীত উত্তরের চেয়ে আলাদা খুঁজে বের করতে এটি বেশ কার্যকর।
করণ শর্মা

6

এক্সডিফের জন্য একটি পিসিএল এক্সটেনশনও রয়েছে:

নির্দিষ্টভাবে:

  • xdiff_string_diff - দুটি স্ট্রিংয়ের ইউনিফাইড পার্থক্য তৈরি করুন

পিএইচপি ম্যানুয়াল থেকে উদাহরণ:

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

1
এক্সডিফ পেকল এক্সটেনশনটি আর রক্ষণাবেক্ষণ করা হয় না, স্পষ্টতই ২০০৮-০7-০১ সাল থেকে একটি স্থিতিশীল মুক্তি প্রকাশিত হয়নি, পেকল.পি.পি.পি.এন.পি. / প্যাকেজ / এক্সডিফ অনুসারে , আমি গ্রহণযোগ্য উত্তর দিয়ে পরামর্শটি শেষ করেছি কারণ এটি আরও নতুন , horde.org/libraries/Horde_Text_Diff/download
মাইক

পিএইচপি এর এক্সডিফের জন্য একটি সহজ ইনস্টল পদ্ধতি আছে? (ডেবিয়ান লিনাক্সের জন্য)
পিটার ক্রাউস

@ মাইকপুরসেল, বাস্তবে এটি এখনও রক্ষণাবেক্ষণ করা হচ্ছে। পিএইচপি 7 সমর্থনকারী সর্বশেষ স্থিতিশীল সংস্করণ 2.0-05-15 এ প্রকাশিত হয়েছে।
ব্যবহারকারী 2513149

@ পিটারক্রস, হ্যাঁ, আছে। এই প্রশ্নটি দেখুন: সার্ভারফল্ট
ব্যবহারকারী 2513149

5

পিয়ার-ভিত্তিক এবং দেখানো সহজ বিকল্প উভয়ই নিয়ে আমার ভীষণ সমস্যা হয়েছিল। সুতরাং এখানে এমন একটি সমাধান রয়েছে যা ইউনিক্স ডিফ কমান্ডকে উপকৃত করে (স্পষ্টতই, আপনাকে ইউনিক্স সিস্টেমে থাকতে হবে বা এটির কাজ করার জন্য একটি উইন্ডোজ ডিফ কমান্ড থাকতে হবে)। আপনার পছন্দসই অস্থায়ী ডিরেক্টরি চয়ন করুন এবং যদি আপনি পছন্দ করেন তবে কোডগুলি ফেরত দিতে ব্যতিক্রমগুলি পরিবর্তন করুন।

/**
 * @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);
  }
}

4

এটি আমি খুঁজে পেয়েছি সেরা।

http://code.stephenmorley.org/php/diff-implementation/

এখানে চিত্র বর্ণনা লিখুন


3
ইউটিএফ -8 দিয়ে সঠিকভাবে কাজ করে না। এটি স্ট্রিংগুলিতে অ্যারে অ্যাক্সেস ব্যবহার করে যা প্রতিটি অক্ষরকে এক বাইট প্রশস্ত হিসাবে বিবেচনা করে। এমবি_স্প্লিট সহ সহজেই ফিক্সেবল শক্ত হওয়া উচিত।
জেলওয়েলার

1
এখানে একটি দ্রুত ফিক্স। শুধু প্রতিস্থাপন $sequence1 = $string1; $sequence2 = $string2; $end1 = strlen($string1) - 1; $end2 = strlen($string2) - 1;সঙ্গে$sequence1 = preg_split('//u', $string1, -1, PREG_SPLIT_NO_EMPTY); $sequence2 = preg_split('//u', $string2, -1, PREG_SPLIT_NO_EMPTY); $end1 = count($sequence1) - 1; $end2 = count($sequence2) - 1;
Gellweiler

এই শ্রেণিটি ফাংশন কম্পিউটটেবলের অক্ষর মোড ব্যবহার করে মেমরির বাইরে চলে যায়।
অ্যান্ডি

1
বর্তমান লিঙ্কটি কোড . iamkate.com/php/diff- বাস্তবায়ন । আমি এটি পরীক্ষা করেছি এবং এটি ইউটিএফ -8 সমর্থন করে না।
কঙ্গুর

3

আপনি যা খুঁজছেন তা হ'ল একটি "ডিফ ডিগ্রী"। একটি দ্রুত গুগল অনুসন্ধান আমাকে এই সমাধানে নিয়ে গেছে । আমি এটি পরীক্ষা করিনি তবে সম্ভবত এটি আপনার প্রয়োজন অনুযায়ী করবে do


আমি এই স্ক্রিপ্টটি সবেমাত্র পরীক্ষা করেছি এবং এটি ভালভাবে কাজ করে - ডেরফ অপারেশনটি খুব দ্রুত সম্পন্ন হয় (আমার পরীক্ষিত সংক্ষিপ্ত অনুচ্ছেদটি প্রক্রিয়া করতে 10 মিমি সময় নেয়) এবং এটি যখন লাইন ব্রেকটি যুক্ত হয়েছিল তখন এটি সনাক্ত করতে সক্ষম হয়েছিল। কোডটি যেমন চালানো হয় তাতে বেশ কয়েকটি পিএইচপি বিজ্ঞপ্তি উত্পন্ন হয় যা আপনি সংশোধন করতে চাইতে পারেন, তবে এটির চেয়ে খুব ভাল সমাধান যদি আপনার theতিহ্যগত পাশাপাশি পাশের ভিন্ন পার্থক্যটি ব্যবহার না করে পার্থক্যগুলিকে ইনলাইন দেখানোর প্রয়োজন হয়।
নোয়েল হোয়াইটমোর


2

আমি পিএইচপি কোর থেকে এই দুর্দান্ত কাজগুলি দেখার পরামর্শ দিচ্ছি:

অনুরূপ_পদ্ধতি - দুটি স্ট্রিংয়ের মধ্যে সাদৃশ্য গণনা করুন

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

লেভেনস্টেইন - দুটি স্ট্রিংয়ের মধ্যে লেভেনস্টেইনের দূরত্ব গণনা করুন

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

সাউন্ডেক্স - একটি স্ট্রিংয়ের সাউন্ডেক্স কী গণনা করুন

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

মেটাফোন - একটি স্ট্রিংয়ের মেটাফোন কী গণনা করুন

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



আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.