截断文本保留关键字

时间:2015-08-05 11:15:36

标签: javascript regex replace

我从搜索结果中检索到一个文本,其中包含一些与搜索到的字符串匹配的单词。

我需要以与Google相似的方式截断文本: enter image description here

如果关键字在整个文本中出现不止一次,那么关键字会突出显示,大多数不包含关键字的文本都会被截断并添加省略号。 你会如何构建一个像这样的Javascript中的正则表达式?

由于

1 个答案:

答案 0 :(得分:1)

Javascript Truncate words like Google

jsBin demo ,快速了解基本代码:

var string = "Lorem Ipsum is simply dummy book text of the printing and text book long...";
var queryString = "book"; // What we want highlighted

var rgxp = new RegExp("(\\S*.{0,10})?("+ queryString +")(.{0,10}\\S*)?", "ig");
// If you want to account for newlines, replace dots `.` with `[\\s\\S]`
var results = [];

string.replace(rgxp, function(match, $1, $2, $3){
  results.push( ($1?"…"+$1:"") +"<b>"+ $2 +"</b>"+ ($3?$3+"…":"") );
});

// Some ways to use/test the above:
//
// console.log( results.join("\n") );
// someElement.innerHTML = results.join("<br>");
// someElement.innerHTML = string.replace(rgxp, "<span>$1<b>$2</b>$3</span>");

<强> Use example: jsBin demo

RegExp:

假设我们有一个很长的字符串,并希望匹配所有 图书 图书 字样,<登记/>  这个正则表达式会这样做:

/book/ig  

ig是(案例)不敏感和全局标志)

但我们不仅需要获得 book ,还需要在该匹配之前和之后获得一些截断的文本部分。假设之前有10个字符,之后是10个字符:

/.{0,10}book.{0,10}/ig

.表示除了换行符之外的任何字符,而{minN, maxN}量词,表示我们想要匹配多少这样的字符

为了能够区分前缀块,匹配后缀块,以便我们可以单独使用它们(即:用于包装在<b>粗体标签等中,让我们使用捕获群组 ()

/(.{0,10})(book)(.{0,10})/ig

上述内容将与

中的Bookbook相匹配
  

预订公寓并阅读漂亮的小蓬松动物”

为了知道何时添加省略号,我们需要使这些块“可选”让我们应用 Lazy Quantifier s ?

/(.{0,10})?(book)(.{0,10})?/ig

现在捕获组可能会为空。与条件运算符?:一起使用作为布尔值,您可以声明省略号:($1 ? "…"+$1 : "")

现在我们捕获的内容将是:

  

预订一个公寓   并阅读了很好的

(我刚刚为视觉效果加粗了queryString)

要修复那些丑陋的单词,我们先添加{追加}任何数字*的非空白字符\S

/(\S*.{0,10})?(book)(.{0,10}\S*)?/ig

结果现在是:

  

预订公寓
  并阅读一本好的小

(请参阅 regex101 上面的正则表达式详细信息)

现在让我们将正则表达式表示法转换为 RegExp字符串(转义后备字符并将ig标记放在第二个参数中)。

new RegExp("(\\S*.{0,10})?(book)(.{0,10}\\S*)?", "ig");

由于使用new RegExp方法,我们现在可以将变量传递到:

var queryString = "book";
var rgxp = new RegExp("(\\S*.{0,10})?("+ queryString +")(.{0,10}\\S*)?", "ig");

最后,为了检索和使用我们捕获的三个群组,我们可以使用.replace()"$1""$2""$3" String parameter内访问它们(请参阅演示) 。
或者为了更自由,我们可以使用一个回调函数代替String参数传递所需的参数.replace(rgxp, function(match, $1, $2, $3){

注意:

此代码不会返回重叠匹配。假设我们在上面的字符串中搜索"an"。它不会为“an”&amp; “和”但仅适用于第一个 "an",因为另一个距离第一个太近,并且正则表达式已经消耗了后面的字符,因为 up-to- 10中的最大 .{0,10}More info

如果源字符串中包含HTML标记,请确保(为了方便起见)仅搜索文本内容(而不是HTML字符串) - 否则将需要更复杂的方法。

有用的资源:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/RegExp
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/replace
http://www.rexegg.com/regex-quickstart.html