【问题标题】:How to find the matching string within the string using regex and javascript?如何使用正则表达式和javascript在字符串中查找匹配的字符串?
【发布时间】:2019-08-29 17:31:03
【问题描述】:

我试图匹配字符串中的模式并获取匹配的子字符串的一部分。

我想做什么?

考虑字符串

I am <user-name id="3" text="myname lname"/> <user-name id="32" text="name1 name2"/> 

我要匹配字符串

&lt;user-name id="3" text="myname lname"/&gt;
&lt;user-name id="32" text="name1 name2"/&gt;

并获取文本属性的值。

所以从上面匹配的子字符串中我想要值“myname lname”和“name1 name2”

我想从原始字符串中提取这些值并创建如下字符串,

"I am myname lname name1 name2"

文本属性的值也应该用粗体显示

所以最终的字符串应该如下所示,

I am <strong>myname lname</strong> <strong>name1 name2</strong>

我试图做什么?

由于我是使用正则表达式的新手,所以我尝试一步一步来。

所以我开始首先匹配下面的模式

let str1 = str.match(/\<(user-name\sid="\d+"\stext=[\w\s]+)\/>/g);

但这给了我null。我不确定如何获得最终输出。

【问题讨论】:

    标签: javascript regex reactjs


    【解决方案1】:

    不建议使用正则表达式解析 HTML 或标签。在我看来,这是一种更好的方法——假设文本以文本开头,其余的是用户名标签

    const str = `I am <user-name id="3" text="myname lname"/> <user-name id="32" text="name1 name2"/>`
    
    let domFragment = document.createElement("div");
    
    domFragment.innerHTML=str;
    
    let text = [domFragment.firstChild.wholeText];
    
    [...domFragment.querySelectorAll("user-name")].forEach(
      ele => text.push(`<strong>${ele.getAttribute("text")}</strong>`)
    );
    console.log(text.join(" "));

    【讨论】:

    • 谢谢。我希望这个嵌入在强标签中的文本是粗体的,但我将它呈现为一个字符串。请告诉我如何解决它。
    • 只需使用innerHTML将其插入容器中
    • 我已经像这样在 div 元素中使用了 text 变量。
      {text}
    • 使用 reactjs。 text 应该返回一个 jsx。
    • 使用了这个,我得到如下输出 I am ,myname lname,name1 name2
    【解决方案2】:

    您可以将字符串解析为 HTML 并使用 DOM 操作来获取值,这是一个示例:

    const content = 'I am <user-name id="3" text="myname lname"/> <user-name id="32" text="name1 name2"/>';
    const parser = new DOMParser();
    const doc = parser.parseFromString(content, 'text/html');
    
    const getTextAttrVal = (n) => {
      if (n.matches && n.matches('user-name')) {
        return `<strong>${n.getAttribute('text')}</strong>`;
      }
      return '';
    }
    
    const recursion = (n) => {
      if (n && n.childNodes && n.childNodes.length) {
        return getTextAttrVal(n) + [...n.childNodes].map(recursion).join('');
      }
      return getTextAttrVal(n) || n.textContent;
    }
    
    const result = [...doc.body.childNodes].map(recursion).join(' ');
    
    console.log(result);

    【讨论】:

    • @mplungjan 我将编辑我的答案以添加缺失的部分。
    • 谢谢。我从像这样的对象中获取此字符串 obj = { property1: "i am ',}
    【解决方案3】:

    首先,一个温和的警告...虽然您有时可以侥幸逃脱,但使用正则表达式解析 HTML 通常是个坏主意。 (关于该主题有一些非常有趣的帖子。)

    至于您的正则表达式,我注意到的第一件事是您缺少匹配 text 属性值所需的引号。我会在检查更多内容后更新此答案...

    在这里,与您最初发布的内容略有不同:

    let matches = str.match(/\&lt;user-name\sid="(\d+)"\s+text="([\w\s]+)"\/&gt;/)

    我刚刚添加了缺少的引号,使其对空格更加灵活,并在括号中将您要从字符串中提取的两部分分组,并取出了外括号。哦,我也去掉了g 标志——不需要。

    matches[1] 将是 id 属性值,matches[2] 将是 text 的值。

    matches[2].split(' ') 将为您进一步分解 text 值。

    【讨论】:

    • 不,我提到的缺失引号解决了问题,这就是答案。我的更新只是做了一些改进。
    • 在检索到匹配的模式后,如何获取“text=”之后的字符串。我可以使用子字符串方法找到单个匹配项。但是如果找到多个匹配项,我必须映射每个匹配项并在“text =”之后提取字符串并将其附加到原始字符串中,并将提取的字符串包含在强标记中怎么做?谢谢。
    • 我更新了一些答案,希望能回答你的问题。请注意,这次我也取出了之前的外部括号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-26
    • 1970-01-01
    • 2020-05-27
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多