【问题标题】:compare two client typed text fields jQuery比较两个客户端键入的文本字段jQuery
【发布时间】:2013-03-29 16:02:04
【问题描述】:

我的 jQuery“比较”功能有一些问题。它的任务是比较两个文本区域并突出显示差异。

例如。在一个文本区域中显示“我的名字是迈克尔”,在另一个文本区域中显示“我的名字是米歇尔”。

我的函数将返回两个输入并突出显示第一个输入中的字符“a”,并突出显示第二个输入中缺少的字符。

这是该函数目前的样子,但它似乎不是 100% 的时间。

$(function () {

$('#btnCompare').on('click', function () {
    compare();
});

function compare() {
    $('#divColLeft').empty();
    $('#divColRight').empty();
    var textOne = $('#taOneComp').val();
    var textTwo = $('#taTwoComp').val();

    var output;
    var outputX;

    var arrTextOne = [];
    var arrTextTwo = [];

    for (var i = 0; i < textOne.length; i++) {
        output = textOne.charAt(i);
        arrTextOne.push(output);
    }
    for (var x = 0; x < textTwo.length; x++) {
        outputX = textTwo.charAt(x);
        arrTextTwo.push(outputX);
    }

    $.each(arrTextOne, function (y, e) {
        if ($.inArray(e, arrTextTwo) == -1) {
            $('#divColLeft').append(e);
            $('#divColLeft').highlight(e);
        } else {
            $('#divColLeft').append(arrTextOne[y]);
        }
    });

    $.each(arrTextTwo, function (z, f) {
        if ($.inArray(f, arrTextOne) == -1) {
            $('#divColRight').append(f);
            $('#divColRight').highlight(f);
        } else {
            $('#divColRight').append(arrTextTwo[z]);
        }
    });
}

});

更新:为了更准确和改进原始问题

如果 some 在两个文本中的任何一个之前包含字符“a”,则应突出显示这一差异。在第一个文本中,应该突出显示“a”,在第二个文本中我想输入一个突出差异的空白区域(缺少的字符)。

【问题讨论】:

  • 您说该函数应该:“突出显示第二个缺失的字符”。您如何突出显示缺少的内容?你会在那个位置插入一个空格字符然后突出显示吗?
  • 过去几天我看起来非常相似 - 并发现 jsdiff 对我非常有效。显示其工作的示例位于this link
  • 弗洛雷明,这是一个正确的预期。还有我应该提到的。

标签: jquery html


【解决方案1】:

只有当两个字符串具有完全相同的长度和相同的单词排列时,您的代码才能工作,否则它会崩溃,即如果您在测试字符串的开头添加一个额外的字符。
经过一些编码后,我设法想出了下面的代码,它比较了两个字符串并找到丢失的字符/单词、多余的字符/单词和错误的拼写:

function compare() {
    var elm1 = document.getElementById("div1"),
        elm2 = document.getElementById("txt"),
        output = document.getElementById("div2"),
        txt1 = elm1.innerHTML,          //original text
        txt2 = elm2.value,              //submitted text
        arr1 = txt1.split(" "),         //split original text to array of words
        arr2 = [];                      //miss matching words will be added here

//filter txt1 and txt2 from matching words and add miss matching to arr2///////
    for (var i in arr1) {
        var match = txt2.match(new RegExp("\\b" + arr1[i] + "\\b"));
        if (match) {
            txt2 = txt2.replace(new RegExp("\\s?" + arr1[i]), "");
            txt1 = txt1.replace(new RegExp("\\s?" + arr1[i]), "");
        } else if (!match) {
            arr2.push(arr1[i]);
        }
    }
//compare miss matching words from original and submitted text, if matching charachters is more that 50% highlight missing and extra characters
    var arr3 = txt2.split(" "), //convert filtered submitted text to words array
        right = elm1.innerHTML,
        wrong = elm2.value;
    for (var a in arr2) {
        for (var b in arr3) {
            var match2 = arr3[b].match(new RegExp("[" + arr2[a] + "]", "g")),
                t = (arr2[a].length > arr3[b].length) ? arr2[a].length : arr3[b].length;
            if (match2 && match2.length >= t * 0.5) { //check for words that look similar
                txt2 = txt2.replace(new RegExp("\\s?" + arr3[b]), "");
                txt1 = txt1.replace(new RegExp("\\s?" + arr2[a]), "");
                var str1 = "",
                    str2 = "",
                    n = 0;
                for (var c = 0; c < t; c++) {
                    if (arr2[a].charAt(c) === arr3[b].charAt(c + n)) {
                        str1 += arr3[b].charAt(c + n);
                        str2 += arr2[a].charAt(c);
                    } else if (arr2[a].charAt(c) !== arr3[b].charAt(c + n)) {
                        if(arr2[a].charAt(c + 1) == arr3[b].charAt(c + n)){
                            str2 += arr2[a].charAt(c).fontcolor("blue");
                            str1 += "_".fontcolor("red");
                            n--;
                        }else if(arr2[a].charAt(c) == arr3[b].charAt(c + n + 1)){
                            str1 += arr3[b].charAt(c + n).fontcolor("orange");
                            n++;
                            c--;
                        }else{
                            str1 += arr3[b].charAt(c + n).fontcolor("red");
                            str2 += arr2[a].charAt(c).fontcolor("green");
                        }
                    }
                }
                wrong = wrong.replace(arr3[b], str1);
                right = right.replace(arr2[a], str2);
            }
        }
    }
//check for extra words//////////////////////////////////////
    extra = txt2.split(" ");
    for(var d in extra){
        wrong = wrong.replace(extra[d], extra[d].fontcolor("grey"));
    }
//check for missing words//////////////////////////////////////
    missing = txt1.split(" ");
    for(var f in missing){
        right = right.replace(missing[f], missing[f].fontcolor("blue"));
    }
    output.innerHTML = wrong;
    elm1.innerHTML = right;
}

DEMO

工作原理:

  1. 比较原始文本和提交的文本并找到匹配的单词并将其删除
  2. 比较两个字符串中的剩余单词
  3. 如果两个词看起来相似(相等的字符 => 占总字符的 50%)
  4. 检查缺失/多余/拼写错误的字符并突出显示它们。
  5. 从两个字符串中删除拼写错误的单词
  6. 将原文中剩余的词高亮为缺失词
  7. 将提交文本中的剩余单词突出显示为额外单词

【讨论】:

  • 伟大的。但是我在您应该添加的问题中看到另一件事,请查看此评论stackoverflow.com/questions/15706827/…
  • 太好了,我将在今天晚些时候测试这段代码,正如@KonradGadzina 所说。如果有些在两个文本中的任何一个之前包含“a”,这是应该突出显示的差异。在第一个文本中,应该突出显示“a”,在第二个文本中我想输入一个突出显示差异的空白区域(丢失的字符)。还更新了我原来的帖子。
  • 完成,我认为最好添加“_”来指示丢失的字符,但如果您希望它是一个空格,我可以更改它。看我的演示
  • 谢谢,我试用了演示,它按预期工作。本周晚些时候将在我自己的解决方案中实施它:)。谢谢
  • @razzak 该函数不匹配包含逗号或点的文本。可能更特殊的字符。这有可能以某种方式添加吗?就像我输入一个包含这些特殊字符的更大句子一样,该函数也应该足够聪明来处理这个问题?提前致谢
【解决方案2】:

我的代码比较第一个 textarea 单词和第二个 textare 单词。例如 ..first textarea 文本是“你好吗”,第二个 textarea 文本是“我很好”。它将比较“how”与“I”和“ are' 与 'am'.. 请尝试此代码...我的 fiddle

  $(function () {

            $('#btnCompare').on('click', function () {
                compare();
                return false;
            });

            function compare() {
                $('#divColLeft').empty();
                $('#divColRight').empty();

                var textOne = $.trim($('#taOneComp').val());
                var textTwo = $.trim($('#taTwoComp').val());

                var TempArr1 = textOne.split(' ');
                var TempArr2 = textTwo.split(' ');
                var arr1 = [];
                for (var i = 0; i < TempArr1.length; i++) {
                    if (TempArr1[i] !== "" && TempArr1[i] !== null) {
                        arr1.push(TempArr1[i]);
                    }
                }

                var arr2 = [];
                for (var i = 0; i < TempArr2.length; i++) {
                    if (TempArr2[i] !== "" && TempArr2[i] !== null) {
                        arr2.push(TempArr2[i]);
                    }
                }
                var minArrLen = arr1.length < arr2.length ? arr1.length : arr2.length;

                for (var x = 0; x < minArrLen; x++) {

                    var maxCharLen = arr1[x].length > arr2[x].length ? arr1[x].length : arr2[x].length;
                    for (var y = 0; y < maxCharLen; y++) {
                        if (arr1[x].charAt(y) == ' ') {
                            $('#divColLeft').append('<span  class="missing">' + arr2[x].charAt(y) + '</span>');

                            $('#divColRight').append('<span class="missmatch">' + arr2[x].charAt(y)) + '</span>';
                        }
                        else if (arr2[x].charAt(y) == ' ') {
                            $('#divColLeft').append('<span class="missing">' + arr1[x].charAt(y) + '</span>');

                            $('#divColRight').append('<span class="missmatch">' + arr1[x].charAt(y)) + '</span>';
                        } else if (arr1[x].charAt(y) == arr2[x].charAt(y)) {
                            $('#divColLeft,#divColRight').append(arr1[x].charAt(y));
                        }
                        else {
                            $('#divColLeft').append('<span  class="missmatch">' + arr1[x].charAt(y) + '</span>');
                            $('#divColRight').append('<span  class="missing">' + arr2[x].charAt(y) + '</span>');
                        }
                    }
                    $('#divColLeft').append(' ');
                    $('#divColRight').append(' ');
                }

                if (minArrLen < arr1.length) {
                    for (var Len = minArrLen; Len < arr1.length; Len++) {
                        $('#divColLeft').append(arr1[Len])
                                        .append(' ');
                    }
                } else if (minArrLen < arr2.length) {
                    for (var Len = minArrLen; Len < arr2.length; Len++) {
                        $('#divColRight').append(arr2[Len])
                                        .append(' ');
                    }
                }
            }
        });

【讨论】:

  • 如果您在第二个输入的开头添加额外的单词或字符,您的代码将会中断。试试“这是一个测试”和“这是一个测试”。
  • 我编写了代码来比较单词...假设如果我们给出“这是一个测试”和“a 这是一个测试”...它会将这个与a进行比较..
  • 嗯,我猜这不是 OP 想要的,它提到了 Its mission is to compare two text areas and highlight the differences
  • 他没有提到确切的比较规则,只是提到了 我的函数将返回两个输入并突出显示第一个输入中的字符“a”,并突出显示第二个输入中缺少的字符。
  • @razzak 是正确的,或者这就是我所追求的。如果有些在两个文本之前包含“a”,这是应该突出显示的差异。在第一个文本中,应该突出显示“a”,在第二个文本中我想输入一个突出差异的空白区域(缺少的字符)。
【解决方案3】:
$(document).ready(function () {

  $('#btnCompare').on('click', function () {
      compare();
  });

  function compareText(textOne, textTwo)
  {
      var len = Math.min(textOne.length, textTwo.length);
      for (var i=0;i<len; i++)
      {
          if (textOne.charAt(i) == textTwo.charAt(i)) continue;

          return i;      // this character is different
      }

      if (textOne.length == textTwo.length) return -1;    // same

      return i;
  }

  function compare() {
      $('#divColLeft').empty();
      $('#divColRight').empty();
      var textOne = $('#taOneComp').val();
      var textTwo = $('#taTwoComp').val();

      var diffIndex = compareText(textOne, textTwo);
      if (diffIndex == -1)
      {
          // TODO: tell user they are identical
          $('#divColLeft').html('Identical');

      } else {

          // if textTwo has more characters, 
          // add a dummy character for highlighting to textOne

          if (diffIndex >= (textOne.length)) textOne += '_';

          var char = textOne.charAt(diffIndex);

          // highlight differing character

          var tmpLeft = textOne.substring(0, diffIndex);
          tmpLeft += "<span style='background-color:yellow;font-weight:bold'>" + char + "</span>";
          tmpLeft += textOne.substring(diffIndex+1);

          $('#divColLeft').html(tmpLeft);
      }
  }
});

【讨论】:

  • 这个周末我会调查这个答案。马上放假了。提前致谢
  • 嗯,这不是一个非常广泛的解决方案。如果有人添加了一个额外的字母怎么办?那么这个字符之后的所有内容都将无法匹配,尽管这是一个微小的差异。
猜你喜欢
  • 2011-10-17
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 2017-12-17
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多