【问题标题】:JS: shorten search results by the words, which were foundJS:通过找到的单词缩短搜索结果
【发布时间】:2020-04-17 10:42:55
【问题描述】:

我正在我的应用程序中搜索标题和描述,任务是缩短搜索结果。例如,如果描述太长(超过 2 行),则应将结果缩短为一两行文本,并突出显示找到的单词。

这是来自 algolia 的示例:

这是我迄今为止尝试过的,但没有按预期工作:

  const truncateHighlightedText = (
    sentence,
    searchExpression,
    truncateLength
  ) => {
    const pattern = new RegExp(
      '\\b.{1,' +
        truncateLength +
        '}\\b' +
        searchExpression +
        '\\b.{1,' +
        truncateLength +
        '}\\b',
      'i'
    );

    return sentence.match(pattern);
  };


const sentence = "Testsdfgbsegsegsrewgserwfgvsrevfse  ewrwer wergwregew    erwgrewgwerg   erwgwr eerg rg g er egr ew  erger  rtggrt tr ert tr tr tg tgr gtr  gtr egrt rtg trg rg e eg";
const searchExpression = "egseg";
const truncateLength = 20;


const result = truncateHighlightedText(sentence, searchExpression, truncateLength);
console.log(result);

https://jsfiddle.net/dwr3qgs0/1/

完成这项任务的最佳方法是什么?

【问题讨论】:

  • 你希望得到什么样的匹配?唯一独立的eg 位于字符串的最末尾,这不匹配,因为.{1 之后至少需要一个字符
  • @CertainPerformance 我希望 searchExpression 和这个词两边的几个词。例如测试sdfgbsegsegsrewgserwfgvsrevfse ewrwer
  • 即使eg 不是一个独立的词?
  • @CertainPerformance 没关系,因为我想从行的两侧添加“...”,但显示独立单词也很棒

标签: javascript reactjs search


【解决方案1】:

您的代码目前与任何内容都不匹配,原因有两个:

  • 您正在使用带有\b 的单词边界,这意味着只有独立单词的匹配项才有效。在您问题的代码中,egseg 在任何地方都不是一个独立的词。在 fiddle 的代码中,eg 是一个独立的词,但它存在于字符串的末尾
  • 您需要在与您的{1,' + truncateLength + '} 匹配的单词前后至少有一个 字符。这就是为什么在小提琴中,eg 不匹配。

如果你想匹配searchExpression任何地方,删除单词边界,并使用{0,,而不是{1,,以防匹配在字符串的开头或结尾:

const truncateHighlightedText = (
  sentence,
  searchExpression,
  truncateLength
) => {
  const pattern = new RegExp(
    '\\b.{0,' +
    truncateLength +
    '}' +
    searchExpression +
    '.{0,' +
    truncateLength +
    '}\\b',
    'i'
  );
  console.log(pattern)

  return sentence.match(pattern);
};


const sentence = "Testsdfgbsegsegsrewgserwfgvsrevfse  ewrwer wergwregew    erwgrewgwerg   erwgwr eerg rg g er egr ew  erger  rtggrt tr ert tr tr tg tgr gtr  gtr egrt rtg trg rg e eg";
const searchExpression = "egseg";
const truncateLength = 30;


const result = truncateHighlightedText(sentence, searchExpression, truncateLength);
console.log(result);

要将...s 添加到包含其他未显示字符的末尾,可选择在环视标记中捕获匹配前后的字符,如果捕获到任何内容,则添加...s:

const truncateHighlightedText = (
  sentence,
  searchExpression,
  truncateLength
) => {
  const pattern = new RegExp(
    '(?<=(.)?)\\b.{0,' +
    truncateLength +
    '}' +
    searchExpression +
    '.{0,' +
    truncateLength +
    '}\\b(?=(.)?)',
    'i'
  );
  const match = sentence.match(pattern);
  return (match[1] ? '...' : '') + match[0] + (match[2] ? '...' : '');
};


const sentence = "Testsdfgbsegsegsrewgserwfgvsrevfse  ewrwer wergwregew    erwgrewgwerg   erwgwr eerg rg g er egr ew  erger  rtggrt tr ert tr tr tg tgr gtr  gtr egrt rtg trg rg e eg";
const searchExpression = "egseg";
const truncateLength = 30;


const result = truncateHighlightedText(sentence, searchExpression, truncateLength);
console.log(result);

无需后视,在任何地方都使用捕获组,而不是 match[0]

const truncateHighlightedText = (
  sentence,
  searchExpression,
  truncateLength
) => {
  const pattern = new RegExp(
    '(.)?(\\b.{0,' +
    truncateLength +
    '}' +
    searchExpression +
    '.{0,' +
    truncateLength +
    '})\\b(.)?',
    'i'
  );
  const match = sentence.match(pattern);
  return (match[1] ? '...' : '') + match[2] + (match[3] ? '...' : '');
};


const sentence = "Testsdfgbsegsegsrewgserwfgvsrevfse  ewrwer wergwregew    erwgrewgwerg   erwgwr eerg rg g er egr ew  erger  rtggrt tr ert tr tr tg tgr gtr  gtr egrt rtg trg rg e eg";
const searchExpression = "egseg";
const truncateLength = 30;


const result = truncateHighlightedText(sentence, searchExpression, truncateLength);
console.log(result);

【讨论】:

  • 另外,添加...的正确方法是什么?在您的示例中,应将其添加到字符串的末尾。如果句子从两端截断,那么... 应该在字符串的两端。
  • 查看编辑,环顾四周捕捉,然后检查匹配数组
  • 只是想澄清一下,是否可以使这个正则表达式跨浏览器?如我所见,回溯在旧版浏览器和 safari stackoverflow.com/questions/51568821/… 中不起作用
  • 不向后看,在各处使用捕获组来提取子字符串
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-11
  • 2021-08-06
  • 1970-01-01
  • 2017-03-09
相关资源
最近更新 更多