【问题标题】:Bold part of String字符串的粗体部分
【发布时间】:2021-03-10 00:22:36
【问题描述】:

在 Javascript 中加粗部分字符串的最佳方法是什么?

我有一个对象数组。每个对象都有一个名称。还有一个输入参数。

例如,如果您在输入中写入“sa”,它会自动在数组中搜索名称中包含“sa”字符串的对象。

当我打印所有名称时,我想将名称中与输入文本一致的部分加粗。

例如,如果我搜索“Ma”:

玛利亚
Ama​​里亚
等等……

我需要一个不使用 jQuery 的解决方案。感谢您的帮助。

PD:最后的字符串在

  • 标签。我使用角度 ng-repeat 创建了一个列表。

    这是代码:

    $scope.users = data;
                    for (var i = data.length - 1; i >= 0; i--) {
                      data[i].name=data[i].name.replace($scope.modelCiudad,"<b>"+$scope.modelCiudad+"</b>");
                    };
    

    ModelCiudad 是输入文本内容变量。而data是对象数组。

    在此代码中,例如,如果 ModelCiudad 是“ma”,则每个

  • 是:
    <b>Ma</b>ria
    

    不是玛里亚

  • 【问题讨论】:

    • 请分享您的尝试。
    • 比&lt;b&gt; 更合适的标签可能是&lt;mark&gt;,它表示在特定上下文中突出显示其相关性的文本。突出显示搜索匹配是&lt;mark&gt; 标签的完美使用。
    • 我认为您正在正确处理替换。似乎所有答案都向您展示了如何替换文本,而真正的问题似乎是数据的呈现方式。这完全取决于您如何渲染/设置此文本。似乎如果您将innerHTML 设置为您的字符串,它将正确呈现,但如果您设置innerText 或textContent,它将按字面意思呈现&lt;b&gt; 标签,而不是将它们呈现为HTML。

    标签: javascript angularjs string


    【解决方案1】:

    您可以使用 Javascript 的 str.replace() 方法,其中 str 等于您要搜索的所有文本。

    var str = "Hello";
    var substr = "el";
    str.replace(substr, '<b>' + substr + '</b>');
    

    以上将仅替换substr 的第一个实例。如果要处理替换字符串中的多个子字符串,则必须使用带有 g 修饰符的正则表达式。

    function boldString(str, substr) {
      var strRegExp = new RegExp(substr, 'g');
      return str.replace(strRegExp, '<b>'+substr+'</b>');
    }
    

    实际上调用boldString 看起来像:

    boldString("Hello, can you help me?", "el"); 
    // Returns: H<b>el</b>lo can you h<b>el</b>p me?
    

    当被浏览器渲染时,它看起来像:Hello you can you help me?

    这是一个带有示例的 JSFiddle:https://jsfiddle.net/1rennp8r/3/


    简洁的 ES6 解决方案可能如下所示:

    const boldString = (str, substr) => str.replace(RegExp(substr, 'g'), `<b>${substr}</b>`);
    

    其中str 是您要修改的字符串,substr 是加粗的子字符串。


    ES12 引入了一个新的字符串方法str.replaceAll(),如果一次替换所有匹配项,则无需使用正则表达式。在这种情况下,它的用法如下所示:

    const boldString = (str, substr) => str.replaceAll(substr, `<b>${substr}</b>`);
    

    我应该提一下,为了使后一种方法起作用,您的环境必须支持 ES6/ES12(或使用 Babel 之类的工具进行转译)。

    另一个重要的注意事项是所有这些方法都区分大小写。

    【讨论】:

    • 嗨,米歇尔!我测试了你的解决方案,但不起作用。如果我有您的示例,结果是:您要搜索的所有 text。
    • 我已经用更好的代码和 jsfiddle 更新了我的答案
    • 我了解你的代码 michel。如果你能看到我更新的问题。我使用 Angular 使用 data[x].name 创建名称列表。 b 标签被转换为字符串。 :(
    • 首先尝试实现我上面的代码,因为替换只会找到匹配的第一个实例,上面的代码将遍历整个字符串。在呈现文本之后执行搜索和粗体功能可能是一个更好的主意,而不是存储结果然后呈现它
    • 我这种情况,不改变字符串,不是粗体也不是b标签。我不更新
    • 的 innerhtml,因为它的列表是动态的。当用户写另一封信时,列表会发生变化。我可能是这里的问题?当用户编写另一个字母来实现所有新创建的 li 时,我可以执行一个函数,但我会在创建 li 之前更改字符串。 PD:如果使用 Div 标签问题是一样的
    【解决方案2】:

    这是一个纯 JS 解决方案,它保留原始大小写(因此忽略查询的大小写):

    const boldQuery = (str, query) => {
        const n = str.toUpperCase();
        const q = query.toUpperCase();
        const x = n.indexOf(q);
        if (!q || x === -1) {
            return str; // bail early
        }
        const l = q.length;
        return str.substr(0, x) + '<b>' + str.substr(x, l) + '</b>' + str.substr(x + l);
    }
    

    测试:

    boldQuery('Maria', 'mar'); // "<b>Mar</b>ia"
    boldQuery('Almaria', 'Mar'); // "Al<b>mar</b>ia"
    

    【讨论】:

    • 这是不区分大小写搜索的答案
    • 此方法仅将粗体应用于第一次出现。即boldQuery('Barbara', 'ar') 将导致'Barbara'
    【解决方案3】:

    我今天遇到了类似的问题 - 除了我想匹配整个单词而不是子字符串。所以如果const text = 'The quick brown foxes jumped' 和const word = 'foxes' 比我希望结果是'The quick brown &lt;strong&gt;foxes&lt;/strong&gt; jumped';但是如果const word = 'fox',我预计不会有任何变化。

    我最终做了类似以下的事情:

    const pattern = `(\\s|\\b)(${word})(\\s|\\b)`;
    const regexp = new RegExp(pattern, 'ig'); // ignore case (optional) and match all
    const replaceMask = `$1<strong>$2</strong>$3`;
    
    return text.replace(regexp, replaceMask);
    

    首先我得到确切的单词,它在一些空格或单词边界之前/之后,然后我用相同的空格(如果有的话)和单词替换它,除了单词被包裹在&lt;strong&gt; 标签中。

    【讨论】:

      【解决方案4】:

      如果你想在 react/javascript 中的索引处设置单词或单个字符的样式,我想出了一个版本。

      replaceAt( yourArrayOfIndexes, yourString/orArrayOfStrings ) 
      

      工作示例:https://codesandbox.io/s/ov7zxp9mjq

      function replaceAt(indexArray, [...string]) {
          const replaceValue = i => string[i] = <b>{string[i]}</b>;
          indexArray.forEach(replaceValue);
          return string;
      }
      

      这是另一种替代方法

      function replaceAt(indexArray, [...string]) {
          const startTag = '<b>';
          const endTag = '</b>';
          const tagLetter = i => string.splice(i, 1, startTag + string[i] + endTag);
          indexArray.forEach(tagLetter);
          return string.join('');
      }
      

      还有一个……

      function replaceAt(indexArray, [...string]) {
          for (let i = 0; i < indexArray.length; i++) {
              string = Object.assign(string, {
                [indexArray[i]]: <b>{string[indexArray[i]]}</b>
              });
          }
          return string;
      }
      

      【讨论】:

        猜你喜欢
        相关资源
        最近更新 更多
        热门标签