为每个匹配的单词添加多个正则表达式常量样式



我必须处理一个基本的查找字符串并添加样式,例如<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-999999。

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;
}

有人能解决这个问题吗?我在用多个其他字符串替换多个字符串中找到了一些东西,但还没有找到有效的解决方案。演示可以在https://jsfiddle.net/rrggrr/rt96ghw2/14/

这里有一个重构程序,它应该能满足您的需求。

我使用了多个替换,第一个负责处理电子邮件,第二个负责处理不属于电子邮件地址的号码。

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

电子邮件regex来自https://www.regular-expressions.info/email.html因为电子邮件对regex来说非常复杂。

此处的原始片段:

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(的值都是来自捕获组的电子邮件。其他值,然后可以使用regex替换来执行请求的其他匹配。

我做的另一个更改是使items组使用锚定标记来链接到谷歌,尽管堆栈片段会阻止弹出窗口,所以锚定标记只会在控制台中抛出一个错误。

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>

最新更新