通过添加跨度突出显示文本文档中的字符串

Posted

技术标签:

【中文标题】通过添加跨度突出显示文本文档中的字符串【英文标题】:Highlight a string from the text document by adding spans 【发布时间】:2018-08-31 09:52:47 【问题描述】:

我是webDevelopment 的新手。我有包含一些文本的字符串。现在我想突出显示该文本文件中的一些单词。所以,我在这里使用这个逻辑

$scope.highlighthtml = function (content,startoffset,endoffset,color) 
          var className = 'mark';
          console.log(content.substring(startoffset, endoffset));
          return content.replace(content.substring(startoffset, endoffset), '<span class="' + className + '">$&</span>');

现在一切正常。但是现在发生的情况是,当第一个单词被突出显示时,然后当它试图突出显示第二个单词时,字符串偏移量由于这种替换而发生了变化。它也需要标签,所以现在偏移量正在改变。现在,当我突出显示一些文本时,下次它不应该使用 span 标签的开始和结束偏移量。那么,我该怎么做呢?

就像"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged"

我有这个字符串。现在,我想突出显示when an unknown printer took a galley of 现在,为此我使用子字符串,因为我从后端本身获取开始和结束。我只用标记标记替换那个字符串。

现在问题就在这之后,如果我想突出显示but also the leap into electronic typesetting,那么我从后端得到的偏移量将没有用,因为在替换第一个字符串时我添加了span标签,所以它占用了span标签偏移量也是如此。所以,它也没有通过提供偏移量来让我得到确切的字符串。它给了我另一个字符串,因为偏移量已经改变。现在,在突出显示偏移的同时,不应通过添加 span 标签来更改。

Ajax 调用 -

jsonDataArray.forEach(function (item) 
                  responseData = $scope.highlightHTML(responseData,item.startOffset,item.endOffset,item.color);
                  $rootScope.data.htmlDocument = responseData.replace(/\n/g, "</br>");;
                );

【问题讨论】:

类似于this 其实不一样 您能发布您的输入、当前输出以及您的预期吗? @ThanatManeenut请查看更新后的问题 一种选择是您存储原始文本并检查字符串在原始文本而不是更新文本上的位置。 【参考方案1】:

您可以通过使用以下逻辑使用字符串的长度来实现这一点。

我在您的文本中将 span 添加到 'simply dummy', 'and typesetting', 'Ipsum has been'

我所做的是在函数调用后更新文本之后,我将初始文本长度和更新文本长度之间的差异添加到再次调用函数的偏移量中,这给了我单词的确切偏移量.

请告诉我它是否适合您。

更新了 ajax:

var initialLength = responseData.length;
var updatedLength = 0;
jsonDataArray.forEach(function(item, index) 
  if (index == 0)
    responseData = $scope.highlightHTML(responseData, parseInt(item.startOffset), parseInt(item.endOffset), item.color);
  else
    $scope.highlightHTML(responseData, parseInt(item.startOffset) + (updatedLength - initialLength), parseInt(item.endOffset) + (updatedLength - initialLength), item.color);
    updatedLength = responseData.length;
    $rootScope.data.htmlDocument = responseData.replace(/\n/g, "</br>");;
);

$(document).ready(function() 
  var text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged";
  var initialLength = text.length;
  var updatedLength = 0;
  var startoffset1 = 15;
  var endoffset1 = 27;
  var startoffset2 = 49;
  var endoffset2 = 64;
  var startoffset3 = 81;
  var endoffset3 = 95;
  console.log(text.substring(startoffset1, endoffset1));
  console.log(text.substring(startoffset2, endoffset2));
  console.log(text.substring(startoffset3, endoffset3));
  text = highlightHTML(text, startoffset1, endoffset1, 'green');
  updatedLength = text.length;
  text = highlightHTML(text, startoffset2 + (updatedLength - initialLength), endoffset2 + (updatedLength - initialLength), 'green');
  updatedLength = text.length;
  text = highlightHTML(text, startoffset3 + (updatedLength - initialLength), endoffset3 + (updatedLength - initialLength), 'green');
  console.log(text);
);

function highlightHTML(content, startoffset, endoffset, color) 
  var className = 'mark';
  console.log('Inside Function: ' + content.substring(startoffset, endoffset));
  return content.replace(content.substring(startoffset, endoffset), '<span class="' + className + '">$&</span>');
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;

【讨论】:

所有偏移量都来自 ajax 响应 我刚刚硬编码...你的显然来自 ajax。这只是您可以使用的逻辑 添加了ajax调用你能看一下吗 我已经添加了 ajax 调用响应。你能检查一下吗 是的,我会立即检查【参考方案2】:

有时候,无缘无故地保持神秘和简洁是件很酷的事......它最终仍然可以不那么神秘!

所以这里我的版本使用 html &lt;mark&gt;&lt;wbr&gt; 标签。

在我看来,没有太多需要融合不相关的功能,它失去了所有的多功能性/可移植性。

let ߐ = document.body
function check(_ૐ)
ߐ.innerHTML=ߐ.innerHTML.replace(_ૐ,"<mark>"+_ૐ+"</mark>")


check("when an unknown printer took a galley of")
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged

mark 标签非常适合突出显示,因为它是为此而生的,wbr 有一些特殊的魔法。

wbr:在 UTF-8 编码的页面上,其行为类似于 U+200B 零宽度空间 码点。特别是,它的行为类似于 Unicode bidi BN 代码 点,这意味着它对双向订购没有影响:123,456 显示,当没有在两行上断开时, 123,456 而不是 456,123。

出于同样的原因,元素不引入连字符 在换行点。使连字符仅出现在结尾 行,请使用软连字符实体 () 代替。

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr

这里的标记会在8s后消失,不会破坏文字。

let ߐ = document.body
function check(_ૐ)
ߐ.innerHTML=ߐ.innerHTML.replace(_ૐ,"<mark>"+_ૐ+"</mark>")
window.setTimeout(Ώ,8000)
function Ώ()
ߐ.innerHTML=ߐ.innerHTML.replace("mark","wbr")

check("when an unknown printer took a galley of")
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged

来源:https://codepen.io/Nico_KraZhtest/pen/mEjBdj

为了您的确切查询,它可以如下所示:

jsonDataArray.forEach(function (item) 
                  responseData = $scope.highlightHTML(responseData,item.startOffset,item.endOffset,item.color);
                  $rootScope.data.htmlDocument = responseData.replace("when an unknown printer took a galley of","<mark>"+"when an unknown printer took a galley of"+"</mark>")
                );

或者,更好:

let search = "when an unknown printer took a galley of"
jsonDataArray.forEach(function (item, search) 
                  responseData = $scope.highlightHTML(responseData,item.startOffset,item.endOffset,item.color)
                  $rootScope.data.htmlDocument = responseData.replace(search,"<mark>"+search+"</mark>")
                )

【讨论】:

嗨,你看到我的高亮功能了吗? 应该很容易适应吧?【参考方案3】:

可以将原始内容保存到全局变量中吗?

因此您无需担心添加的 span 标签会更改偏移量。

更新代码

var responseData;
function readFile() 
    responseData = 'Lorem ipsum dolor sit amet, consectetur .....'


var highlightNeeded = []

jsonDataArray.forEach(function (item) 
    var actualText = responseData.substring(item.startOffset, item.endOffset)
    highlightNeeded.push(highlightNeeded)
);

// call this after foreach finished 
var tmpData = $scope.highlightHTML(responseData, highlightNeeded, item.color);
$rootScope.data.htmlDocument = tmpData.replace(/\n/g, "</br>");;

$scope.highlightHTML = function (content, listOfText, color) 
    var className = 'mark';
    listOfText.forEach(function (text) 
        var regex = new RegExp(text, 'gi')
        content.replace(regex, '<span class="' + className + '">$&</span>');
    )

【讨论】:

你能告诉我什么时候显示然后我想显示突出显示的文件 一件事内容是指整个文件或我要突出显示的文件 你可以应用我更新的代码,想法是从偏移量中找到什么文本并将其保存在数组中,完成所有这些后你可以使用正则表达式突出显示你需要的所有文本跨度>

以上是关于通过添加跨度突出显示文本文档中的字符串的主要内容,如果未能解决你的问题,请参考以下文章

将文本文档中的字符串值分离到熊猫数据框中

labview如何读取文本文档中某一行的字符串

如何从python中的文本文档中删除所有标点符号和其他符号?

在图像文本文档中随机生成合成噪声

Java提取文本文档中的所有网址(小案例介绍正则基础知识)

python 读取文本文档中的数据