【问题标题】:How to highlight word in a string using coordinates in javascript?如何使用javascript中的坐标突出显示字符串中的单词?
【发布时间】:2020-02-04 09:35:16
【问题描述】:

我在一个句子中突出显示多个单词时遇到问题。我有如下文本数据:

"The furnishing of Ci Suo 's home astonished the visitors: a home of 5 earthen and wooden structures, it has a sitting room with two layers of glass as well as a warehouse filled with mutton and ghee ."

还有一个对象数组:

entities: [
      {
        "entity_type": "PERSON",
        "index": [
          18,
          26
        ],
        "namedEntity": "Ci Suo 's"
      },
      {
        "entity_type": "CARDINAL",
        "index": [
          69,
          69
        ],
        "namedEntity": "5"
      },
      {
        "entity_type": "CARDINAL",
        "index": [
          130,
          132
        ],
        "namedEntity": "two"
      }
    ]

我需要像这样突出显示它:

这是我迄今为止尝试过的:

const find = entities; // word to highlight
let str = text; // contain the text i want  to highlight

for (let i = 0; i < find.length; i++) {
  str = str.replace(new RegExp(find[i], "g"), match => {
    const color = randomColor();
    return `<span style="background: ${color}">${match}</span>`;
  });
}

使用这种方法,我遇到了一些错误,例如

  • 如果我有像“an”这样的词,后面的标签可以在下一次迭代中匹配
  • 两个相同的词获得相同的标签

如果您有其他方法可以提供帮助,谢谢

【问题讨论】:

  • new RegExp(find[i].namedEntity, "g") 应该可以工作,但是如果您已经有索引,我不明白为什么要再次搜索它
  • 尝试包装短语以在单词边界中查找,例如new RegExp(`\\b${find[i].namedEntity}\\b`, 'g')。这应该可以帮助您解决问题 #1
  • @DmitryReutov 是的,我想是的。但后来如果我用 包裹一个单词,句子的长度会变长,索引将不再有效

标签: javascript html css vue.js


【解决方案1】:

我认为您在实体数组中拥有所有可用信息来替换原始文本中的文本。您可以使用以下内容。

var text = "The furnishing of Ci Suo 's home astonished the visitors : a home of 5 earthen and wooden structures , it has a sitting room with two layers of glass as well as a warehouse filled with mutton and ghee ."
var entities = [
      {
        "entity_type": "PERSON",
        "index": [
          18,
          26
        ],
        "namedEntity": "Ci Suo 's"
      },
      {
        "entity_type": "CARDINAL",
        "index": [
          69,
          69
        ],
        "namedEntity": "5"
      },
      {
        "entity_type": "CARDINAL",
        "index": [
          130,
          132
        ],
        "namedEntity": "two"
      }
    ]


function buildText(text, entities) {
  var newText = text;
  
  entities.forEach(({entity_type, namedEntity, index}) => {
    newText = newText.replace(namedEntity, `<span class=${entity_type.toLowerCase()}>${namedEntity}</span>`)
  } )
  
  return newText;
}

document.getElementById('content').innerHTML = buildText(text, entities);
.person {
  background-color: red;
}

.cardinal {
  background: cyan;
}
&lt;div id='content' /&gt;

【讨论】:

    【解决方案2】:

    正如@Phill 上面评论的那样,您可以将单词边界(例如\b)添加到需要找到的单词中,这应该会有所帮助。 试试这个:

    for(let i = 0; i < find.length; i++) {
       const findRegExp = new RegExp("\\b" + find[i].namedEntity + "\\b","g");
       str = str.replace(findRegExp, function (match, index, wholeStr) {
            const color = randomColor();
            return `<span style="background: ${color}">${match}</span>`;
        });
    }
    

    【讨论】:

      猜你喜欢
      • 2012-09-09
      • 2020-10-12
      • 2020-10-16
      • 2018-12-12
      • 2018-07-31
      • 2021-09-14
      • 2017-08-29
      • 2020-10-18
      • 1970-01-01
      相关资源
      最近更新 更多