javascript将obj传递给字符串替换

时间:2018-02-11 08:23:27

标签: javascript regex

我有键和值的对象,我想传递这个对象来替换函数并用值

替换键

sudoers
function highlight(){
  var mapObj = {} //this is the obj to pass to replace

  //get the input value
  var whatInTextInput = document.querySelector(".toGetText").value;

  //trim and split the string into array of words
  var whatInTextInput_words_array = whatInTextInput.trim().split(' ');
  
  //build the object with keys and value
  for(let item in whatInTextInput_words_array){
    mapObj[whatInTextInput_words_array[item]] = "<mark class='highlight'>"+[whatInTextInput_words_array[item]]+"</mark>"
  }
    
  // this is just the test string
  var str = "I have a cat, a dog, and a goat.";
  
  //here how to pass mapObj instead of /cat|dog|goat/gi ???
  str = str.replace(/cat|dog|goat/gi, function(key) {
    return mapObj[key];
  });
   
  //show the final result
  document.querySelector(".inputText").innerHTML = str;
}
.highlight {
  background: yellow;
}

如果我没有输入其他单词,我的结果是未定义的。

如何传递具有键和值的<button onclick="highlight()">Highlight</button> <input type="text" class="toGetText"/> <div class="inputText">I have a cat, a dog, and a goat.</div> obj来替换函数而不是const值mapObj

1 个答案:

答案 0 :(得分:1)

您必须从用户输入中获取单词并从中构建正则表达式。 .replace只需要一个正则表达式;它没有直接处理对象。

这里有一些微妙的要点:您需要转义任何正则表达式元字符,并且您需要确保以后列出任何作为其他键前缀的键(例如,如果您同时具有{{1} }和cat,正则表达式需要caterpillar,而不是caterpillar|cat,否则cat|caterpillar永远不会匹配。)

在这种情况下,拥有映射对象不是一个好主意,或者:您希望进行不区分大小写的匹配,这样您就不能预先计算替换字符串:如果您没有&# 39; t标准化匹配的字符串,你只需得到caterpillar(因为例如undefined不是密钥),如果你这样做,你就会破坏文本的原始案例(例如CaT将变为CaT(全部小写))。

最简单的解决方案是从输入字符串中取出所有单词,按降序长度排序(以确保后面列出任何前缀字符串),转义所有正则表达式元字符,然后将它们与<mark class="highlight">cat</mark>连接起来。但是,如果输入列表为空,那将导致|(一个匹配无处不在的字符串),并且我们希望它无处匹配,所以在这种情况下只使用''(一个永远不会出现的正则表达式)匹配)。

然后获取目标元素的/^(?!)/,进行替换(动态计算替换HTML以保留原始大小写,并确保正确地转义所有HTML元字符),并将其放回{{1 }}

有点像这样:

&#13;
&#13;
.textContent
&#13;
.innerHTML
&#13;
function highlight() {
  const mapObj = {};
  const whatInTextInput = document.querySelector(".toGetText").value;
  const whatInTextInput_words_array = whatInTextInput.match(/\S+/g) || [];
  
  const regex_str = whatInTextInput_words_array.sort(function (a, b) {
    const na = a.length, nb = b.length;
    return (
      na > nb ? -1 :
      na < nb ? 1 :
      a < b ? -1 :
      b < a ? 1 :
      0
    );
  })
  .map(s => s.replace(/\W/g, "\\$&"))
  .join('|');
  const regex = whatInTextInput_words_array.length ? new RegExp(regex_str, 'gi') : /^(?!)/;

  const inputText = document.querySelector('.inputText');
  const str = inputText.textContent;
  
  inputText.innerHTML = str.replace(regex, function (word) {
    return (
      '<mark class="highlight">' +
      word.replace(/[<>&]/g, c => '&#' + c.charCodeAt(0) + ';') +  // hacky HTML escape
      '</mark>'
    );
  });
}
&#13;
&#13;
&#13;