Javascript替换已替换的文本

时间:2018-04-07 11:51:30

标签: javascript html

我有两个用HTML编写的textareas:

<textarea id="checked-words"></textarea>
<br />
<textarea id="words" onkeyup="displayColoredText()"></textarea>
<div id="text-to-insert"></div>

(进入div元素,我将使用JavaScript

插入文字

我的任务是在div部分写入第二个textarea中的文字,并将第一个textarea中字符串的出现设为红色。
示例
如果第一个textarea包含以下字词:aaaaab,第二个包含aaab,则所有字符都必须为红色。如果第二个包含abaa,则div部分中的所有字符都不会为红色。

这是我的JavaScript函数,用于显示和着色文本:

function displayColoredText() {
//Displays the colored text below the second textarea

//Find the two textareas
var firstTextArea = document.getElementById('checked-words');
var secondTextArea = document.getElementById('words');

//Split by spaces
var checkedWords = firstTextArea.value.split(" ");
var text = secondTextArea.value.split(" ");

var textToInsert = secondTextArea.value;

for(i in checkedWords) {
    console.log(checkedWords.length);
    textToInsert = textToInsert.replace(new RegExp(checkedWords[i], 'g'), '<span class="insertRed">' + checkedWords[i] + '</span>');
}

document.getElementById('text-to-insert').innerHTML = textToInsert;
}

我的问题是,如果第一个textarea包含aaaaab且第二个包含{{1},则不会考虑已替换的文本只有前三个字符是红色的,而不是整个字符串。我该如何解决这个问题?

编辑:问题的屏幕截图 enter image description here

2 个答案:

答案 0 :(得分:2)

来自第二个文本区域的原始输入是纯文本,而不是HTML,因此这是&#34;状态&#34;您想要执行此操作的数据。

这将是我在评论中提到的实现它的方式,记录哪些位置首先匹配,然后简单地循环遍历所有字符以将它们包装在每个范围中:

function displayColoredText() {
  //Displays the colored text below the second textarea

  //Find the two textareas
  var firstTextArea = document.getElementById('checked-words');
  var secondTextArea = document.getElementById('words');

  //Split by spaces
  var checkedWords = firstTextArea.value.split(" ");
  var text = secondTextArea.value;
  // empty array with keys 0 to length-1 set to undefined
  var markedMatches = new Array(secondTextArea.value.length);

  for (var i = 0, l = checkedWords.length; i < l; ++i) {
    var checkedWord = checkedWords[i],
      start = 0,
      matchPos;
    // check for match from current starting position
    while ((matchPos = text.indexOf(checkedWord, start)) !== -1) {
      // mark positions from current match start to that plus length of match
      for (var k = matchPos, m = matchPos + checkedWord.length; k < m; ++k) {
        markedMatches[k] = true;
      }
      // advance starting position to continue searching
      start = matchPos + 1;
    }
  }

  var textToInsert = '';
  for (var i = 0, l = text.length; i < l; ++i) {
    // wrap in span if markedMatches contains true at this position
    textToInsert += (markedMatches[i] ? '<span class="match">' + text[i] + '</span>' : text[i]);
  }
  document.getElementById('text-to-insert').innerHTML = textToInsert;
}

https://jsfiddle.net/t9xjzkaw/

正如我所说的那样,你可以更精确地将匹配作为间隔收集,或者将多个相邻的匹配字符放入单个span元素中,而不是将每个匹配字符单独包装......但这可以完成基本工作。 / p>

答案 1 :(得分:0)

您的问题是如何更换字符串。你的第一个字符串是'aaa aab'。在'aaab'中替换'aaa'后,你得到'&lt; span class =“insertRed”&gt; aaa&lt; / span&gt; b'。试图在这个字符串中找到'aab'将没有结果。你必须从你的原始字符串替换,并以某种方式将两者结合起来。我不知道该怎么做,但我希望这能让你走上正轨。

编辑: 我认为这会奏效: 不是替换字符串中的文本,而是将起始坐标放在数组中,将结束坐标放在第二个数组中。为找到的每个单词继续这样做。然后在所有开始坐标处插入字符串'&lt; span class =“insertRed”&gt;'。在所有结束坐标处,插入字符串'&lt; span&gt;'。这是JS:

function displayColoredText() {
    //Displays the colored text below the second textarea
    //arrays with coordinates
    var beginnings = [];
    var ends = [];
    //Find the two textareas
    var firstTextArea = document.getElementById('checked-words');
    var secondTextArea = document.getElementById('words');

    //Split by spaces
    var checkedWords = firstTextArea.value.split(" ");
    var text = secondTextArea.value.split(" ");

    var textToInsert = firstTextArea.value;

    for(i in checkedWords) {
        console.log(checkedWords.length);
        if (firstTextArea.value.indexOf(checkedWords[i]) != -1) {
            beginnings.push(firstTextArea.value.indexOf(checkedWords[i]));
            ends.push(firstTextArea.value.indexOf(checkedWords[i]) + checkedWords[i].length);
        }
    }
    beginnings.sort(function(a, b){return b-a});
    ends.sort(function(a, b){return b-a});
    for (b in beginnings) {
        textToInsert = textToInsert.slice(0, ends[b]) + "</span>" + textToInsert.slice(ends[b]);
        textToInsert = textToInsert.slice(0, beginnings[b]) + '<span class="insertRed">' + textToInsert.slice(beginnings[b]);
    }
    document.getElementById('text-to-insert').innerHTML = textToInsert;
}

此代码未经测试,请告诉我,如果某些内容不起作用,我会更改它。基本上,我正在做的不是替换事件,而是先找到它们,将它们放在数组中,然后在这些坐标处插入正确的文本。我希望这有帮助!