【问题标题】:multiple regex const - add style for each matched word [closed]多个正则表达式 const - 为每个匹配的单词添加样式 [关闭]
【发布时间】:2021-01-26 01:08:09
【问题描述】:

我必须处理一个基本的查找字符串并添加样式,例如。 <button onclick="copyData(event)" class="${orders.test(match)}">${match}</button> 但我想将相同的方法应用于以下所有四个正则表达式匹配;匹配对应的.css样式。

orders:    example: 975612345678. range: 975600000000-975699999999 
customers: example: 1712345678901. range: 1700000000000-1799999999999
emails:    example: word@test.com, 01234@numbers.tk
items:     example: 32101234, 1012345678. range: 00000000-99999999, range: 1000000000-1099999999

我们可以看到它错过了emailsitems 的正则表达式:范围:00000000-99999999。

const orders = /\b9756[0-9]{8}\b/;
const customers = /\b17[0-9]{11}\b/;
const emails = ??
const items = ?? and /\b10[0-9]{8}\b/;
for (var i = 0; i < list.length; i++) {
    let text = list[i].textContent;
    // Make the regex have boundary characters to ensure that it's checking against the whole number, rather than a part. example: 975612345678. range: 975600000000-975699999999  
    const orders = /\b9756[0-9]{8}\b/; 
    list[i].innerHTML = text.replace(
        // Replace all number sequences in the text
        /\d+/g,
        // Replace by checking if the replacement text matches "const orders"(regex) to determine color
        (match) => `<button onclick="copyData(event)" class="${orders.test(match)}">${match}</button>`
    )
}
/*.true needs to be .orders */
.true {
  background-color: green;
}
.orders {
    background-color: green;
}

/* corresponding regex "orders, customers, emails and items" needs to match style */
.customers {
    background-color: red;
}
.emails {
    background-color: blue;
}
.items {
    background-color: yellow;
}

谁有解决问题的办法?我在Replace multiple strings with multiple other strings 找到了一些东西,但还没有找到可行的解决方案。 可以通过https://jsfiddle.net/rrggrr/rt96ghw2/14/查看演示

【问题讨论】:

    标签: javascript regex replace


    【解决方案1】:

    这里的重构应该可以满足你的需求。

    我正在使用多个替换,第一个处理电子邮件,第二个处理不属于电子邮件地址的数字。

    不幸的是,它不一定是性能最高的代码,但它适用于给定的输入。

    来自https://www.regular-expressions.info/email.html 的电子邮件正则表达式,因为电子邮件对于正则表达式来说非常复杂。

    这里是原始sn-p:

    var list = document.getElementsByClassName("message__content")
    //window.copyData = copyData;
    // use number manipulation to check if orders/customers/items are actually real values, as we don't need a regex for it since they are just ranges. If they are more complicated, then we could replace it with a regex
    function isOrder(string) {
      return Number(string) >= 9756E8 && Number(string) < 9757E8;
    }
    
    function isCustomer(string) {
      return Number(string) >= 17E11 && Number(string) < 18E11;
    }
    
    function isItem(string) {
      return (Number(string) >= 0 && Number(string) < 1e8) || (Number(string) >= 1E9 && Number(string) < 1.1E9)
    }
    
    for (var i = 0; i < list.length; i++) {
      // Email regex from https://www.regular-expressions.info/email.html - many more complicated regexes for it on this site as well. Emails are super complicated
      const emailRegex = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;
      let text = list[i].textContent;
    
      list[i].innerHTML = text.replace(emailRegex, '<button onclick="copyData(event)" class="copyData emails">$&</button>')
        .replace(
          // Replace all number sequences in the text
          // Make the regex have boundary characters to ensure that it's checking against the whole number, rather than a part. example: 975612345678. range: 975600000000-975699999999 
          // Specifically disclude anything that is an email address via composition since we look at emails already in the first replacement
          new RegExp(`\\b(?!${emailRegex.source})\\d+\\b`, 'gi'),
          // Replace by checking if the replacement text matches any of the number based checks to determine color
          (match) => {
            if (isOrder(match)) {
              return `<button onclick="copyData(event)" class="copyData orders">${match}</button>`
            } else if (isCustomer(match)) {
              return `<button onclick="copyData(event)" class="copyData customers">${match}</button>`
            } else if (isItem(match)) {
              return `<button onclick="copyData(event)" class="copyData items">${match}</button>`
            } else {
              return match;
            }
          }
        )
    }
    
    
    
    function copyData(e) {
      const textarea = document.createElement('textarea');
      textarea.textContent = e.currentTarget.innerText;
      textarea.style.position = 'fixed'; // Prevent scrolling to bottom of page in MS Edge.
      document.body.appendChild(textarea);
      textarea.select();
      document.execCommand('copy');
      document.body.removeChild(textarea);
    }
    for (const elem of document.querySelectorAll('.copyData')) {
      elem.addEventListener('click', copyData)
    }
    div {
      white-space: pre;
    }
    
    .orders {
      background-color: green;
    }
    
    
    /* corresponding regex "orders, customers, emails and items" needs to match style */
    
    .customers {
      background-color: red;
    }
    
    .emails {
      background-color: blue;
    }
    
    .items {
      background-color: yellow;
    }
    <div class="message__content">
    orders:    example: 975612345678. range: 975600000000-975699999999 
    customers: example: 1712345678901. range: 1700000000000-1799999999999
    emails:    example: word@test.com, 01234@numbers.tk
    items:     example: 32101234, 1012345678. range: 00000000-99999999, range: 1000000000-1099999999
    </div>
    <div class="message__content">
    GOOD:
    orders:    example: 975612345678 AND 140123456789
    customers: example: 1712345678901.
    emails:    example: word@test.com
    items:     example: 32101234 AND 1012345678
    
    WRONG:
    orders:    example: 975612345678test AND test140123456789
    customers: example: 1712345678901test AND test1712345678901
    emails:    example: word@test.comtest
    items:     example: 32101234test AND test1012345678
    </div>

    这是一个重构,允许数字不影响电子邮件。这使用 string#split 使用捕获组使该组最终出现在结果数组中。然后我们映射数组,任何具有奇数索引 (index % 2 === 1) 的值都是来自捕获组的电子邮件。其他值,然后可以使用正则表达式替换来执行请求的其他匹配。

    我所做的另一项更改是让项目组使用锚标记链接到 google,尽管堆栈 sn-ps 阻止弹出窗口,因此锚标记只会在控制台中抛出错误。

    var list = document.getElementsByClassName("message__content")
    
    //window.copyData = copyData;
    // use number manipulation to check if orders/customers/items are actually real values, as we don't need a regex for it since they are just ranges. If they are more complicated, then we could replace it with a regex
    function isOrder(string) {
      return (Number(string) >= 9756E8 && Number(string) < 9757E8) || (Number(string) >= 14E10 && Number(string) < 15E10)
    }
    
    function isCustomer(string) {
      return Number(string) >= 17E11 && Number(string) < 18E11;
    }
    
    function isItem(string) {
      return (Number(string) >= 0 && Number(string) < 1e8) || (Number(string) >= 1E9 && Number(string) < 1.1E9)
    }
    
    for (var i = 0; i < list.length; i++) {
      // Email regex from https://www.regular-expressions.info/email.html - many more complicated regexes for it on this site as well. Emails are super complicated
      const emailRegex = /(\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b)/gi;
      // Splitting using a capturing group makes that group end up in the result
      let text = list[i].textContent;
      let splitText = text.split(emailRegex);
      list[i].innerHTML = splitText.map((text, index) => {
        if (index % 2 === 1) {
          // This is an email address
          return `<button onclick="copyData(event)" class="copyData emails">${text}</button>`
        }
        return text.replace(/\d+/g, (match) => {
          if (isOrder(match)) {
            return `<button onclick="copyData(event)" class="copyData orders">${match}</button>`
          } else if (isCustomer(match)) {
            return `<button onclick="copyData(event)" class="copyData customers">${match}</button>`
          } else if (isItem(match)) {
            return `<a href="http://google.com?q=${match}" target="_blank" rel=”noreferrer noopener”><button onclick="copyData(event)" class="button copyData items">${match}</button></a>`
          } else {
            return match;
          }
        })
      }).join('')
    }
    
    
    
    function copyData(e) {
      const textarea = document.createElement('textarea');
      textarea.textContent = e.currentTarget.innerText;
      textarea.style.position = 'fixed'; // Prevent scrolling to bottom of page in MS Edge.
      document.body.appendChild(textarea);
      textarea.select();
      document.execCommand('copy');
      document.body.removeChild(textarea);
    
    }
    for (const elem of document.querySelectorAll('.copyData')) {
      elem.addEventListener('click', copyData)
    
    }
    div {
      white-space: pre;
    }
    
    .orders {
      background-color: green;
    }
    
    
    /* corresponding regex "orders, customers, emails and items" needs to match style */
    
    .customers {
      background-color: red;
    }
    
    .emails {
      background-color: blue;
    }
    
    .items {
      background-color: yellow;
    }
    <div class="message__content">
    orders:    example: 975612345678. range: 975600000000-975699999999 
    customers: example: 1712345678901. range: 1700000000000-1799999999999
    emails:    example: word@test.com, 01234@numbers.tk
    items:     example: 32101234, 1012345678. range: 00000000-99999999, range: 1000000000-1099999999
    </div>
    <div class="message__content">
    GOOD:
    orders:    example: 975612345678 AND 140123456789
    customers: example: 1712345678901.
    emails:    example: word@test.com
    items:     example: 32101234 AND 1012345678
    
    WRONG:
    orders:    example: 975612345678test AND test140123456789
    customers: example: 1712345678901test AND test1712345678901
    emails:    example: word@test.comtest
    items:     example: 32101234test AND test1012345678
    </div>

    【讨论】:

    • 啊,太完美了!是否也可以使按钮重定向到某个 URL。例如,当仅单击按钮“项目:32101234”以将其链接到 website.com/search?q=32101234 并复制
    • 我只见过一个小“错误”,即单词或字母不小心粘在数字上。例如,不小心忘记了一个空格。 jsfiddle.net/rrggrr/r8mxye5a/12
    • @RRG,我已经解决了你问的问题。我让这些项目有一个指向谷歌搜索页面的链接,但由于权限问题,它在堆栈溢出时不起作用。
    • 非常感谢!小东西。如何删除字符串中的所有点,如 12.34.5678 --> 12345678 in items --> return (Number(string) >= 0 && Number(string)
    • 和一个正则表达式,用于从客户 1712 3456 7890 1 --> 1712345678901 中删除空格。我认为它也可以在事后从所有值中删除所有空格和点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 2012-01-06
    • 1970-01-01
    相关资源
    最近更新 更多