使用javascript,我如何循环regex匹配并将字符串拆分为由超链接划分的数组



我从一个api中检索到一个字符串,如下所示:

"If you <a href='https://example.com'>Click here</a> then <a href='https://example.net'>Click here</a>."

我正在尝试创建一个看起来像这样的数组:

[
"If you "
<a ... </a>
" then "
<a ... </a>
"."
]

基本上,我想在不使用危险的设置innerHtml方法的情况下将其渲染为预期的样子。我已经有了我的正则表达式匹配,我只是想找出最聪明的方法来循环它们并构建它。我只是输入了这个,但在看到输出后意识到它显然有缺陷,我需要知道从哪里开始基于最后一个匹配的子字符串,但似乎无法解决这个问题。赞赏任何指导

let noticeTextArr: (string | JSX.Element)[] = [];
if(notice.label !== undefined) {
const reg = /<a.+?href="(.+?)".*?>(.+?)</a>/g;
let result;
while((result = reg.exec(notice.label)) !== null) {
if(result.index > 0) {
noticeTextArr.push(notice.label.substring(0, result.index))
}
noticeTextArr.push(<a href={result[1]}>{result[2]}</a>);      
}
}

这里有一个有点令人毛骨悚然但运行良好的正则表达式。它基本上与您对增强所做的方法相同。

function convertToJSX(text: string) {
const regex = /<s*a[^>]*href=["']([^>]*)["'][^>]*>(.*?)<s*/s*a>/g;
const matches = text.matchAll(regex);
const noticeTextArr: (string | JSX.Element)[] = [];
let lastIndex = 0;
for (const match of matches) {
const [fullMatch, href, content] = match;
noticeTextArr.push(text.substring(lastIndex, match.index));
noticeTextArr.push(<a href={href}>{content}</a>);
lastIndex = match.index + fullMatch.length;
}
if (lastIndex < text.length) {
noticeTextArr.push(text.substring(lastIndex));
}
return noticeTextArr;
}

你可以试试这个:

const text = "If you <a href='https://example.com'>Click here</a> then <a href='https://example.net'>Click here</a>.";
const array = text.split(/(<a.+?href=["'].+?["'].*?>.+?</a>)/g);

当您将regex作为一个整体组进行拆分时,js会拆分文本,同时返回捕获的组。因此,我更改了正则表达式以删除内部组。

const data = "If you <a href='https://example.com'>Click here</a> then <a href='https://example.net'>Click here</a>."

const c = data.split(' ')
let i = 0
let res = ''
let arr = []
while(i< c.length){
if(c[i] === '<a') {
arr.push(res)
res = c[i]
i++;
while(!c[i].includes('</a>')) {
res += " "+c[i]
i++
} 
res += " "+c[i++]
arr.push(res)
res ='';
} else {
res +=" "+ c[i++]
}
}  
console.log(arr)

split与具有捕获组的正则表达式一起使用

const text = "If you <a href='https://example.com'>Click here</a> then <a href='https://example.net'>Click here</a>.";
console.log(text.split(/(<as[^>]*>[^<]*</a>)/));

查看正则表达式如何工作

解释

EXPLANATION
--------------------------------------------------------------------------------
(                        group and capture to 1:
--------------------------------------------------------------------------------
<a                       '<a'
--------------------------------------------------------------------------------
s                       whitespace (n, r, t, f, and " ")
--------------------------------------------------------------------------------
[^>]*                    any character except: '>' (0 or more
times (matching the most amount
possible))
--------------------------------------------------------------------------------
>                        '>'
--------------------------------------------------------------------------------
[^<]*                    any character except: '<' (0 or more
times (matching the most amount
possible))
--------------------------------------------------------------------------------
<                        '<'
--------------------------------------------------------------------------------
/                       '/'
--------------------------------------------------------------------------------
a>                       'a>'
--------------------------------------------------------------------------------
)                        end of 1

因为解析html元素很困难,我建议使用Document.createElement((让浏览器解析和拆分文本:

var txt = "If you <a href='https://example.com'>Click here</a> then <a href='https://example.net'>Click here</a>.";
var el = document.createElement( 'html' );
el.innerHTML = txt;
var result = Array.from(el.querySelector('body').childNodes).map(function(ele) {
return ele.nodeType == Node.TEXT_NODE ? ele.textContent : ele.outerHTML;
});
console.log(result);

最新更新