在 html 字符串 (regex)(javascript) 中查找所有 p 标签



(update( 我已经通过创建一个新的 dom 对象并迭代子节点解决了没有正则表达式的问题。是我的高级开发人员想要它正则表达式。他的逻辑是,该函数将被多次调用,我们不想费心创建一个新的 dom 节点并操纵它只是为了获取第一行 html 文本。

(背景(有一个 html 文本,我需要从中检索第一行。(如果只是像<p></p>这样的空格,我需要看看下一行。假设我有逻辑来检查它是否基本上是空的(

(目标(在所有p或标题标签中查找文本(h1h2..(

(条件(HTML 格式正确。行仅由ph标记分隔。ph标记不会同时出现。

就像输入是...

<ul>
<li><p>hello1</p></li>
<li><p>hello2</p></li>
</ul>
<h3> <strong>hello3</strong> </h3>
<h4> <strong><hello4></strong> </h3>
<hr>
<p> <a href="sth">sth</a> </p>

我想得到的输出是

<p>hello1</p>
<p>hello2</p>
<strong>hello3</strong>
<strong><hello4></strong>
<a href="sth">sth</a>

我需要用正则表达式解决这个问题。

我已经这样做了,它是错误的。我发布了这个问题,因为我不确定我是否应该修改它或只是使用全新的方法/功能。

function isAllWhiteSpace(txt) {
if (txt) {
txt = txt.replace(/s/g, '').replace(/&nbsp/g, '') // remove white space
txt = txt.replace(/<[^>]*>|<[^>/]/>/g, '') // remove tag
if (txt.length) return false;
}
return true;
}
function getFirstLine(txt) {
const reFirstLine = /<(p|h3|h4)>(.*?)<(/p|/h3|/h4)>/;
while (txt) {
const m = reFirstLine.exec(txt);
if (m) {
if (isAllWhiteSpace(m[2])) { // if all white text, search for the next p or h tag
// this is faulty.
// I omitted cases where some string comes before <p> or <h>, like <ul><li><p>...
txt = txt.slice(m[0].length + 1);
} else {
return m[2];
}
}
}
return '';
}

您可以使用querySelectorAll来查找所需的任何标签,用逗号分隔,然后循环项目:

  • 获取修剪的内容
  • 如果内容只是空格,则忽略
  • 检查父元素,如果项目属于 BODY,则添加当前内容,不带外部标签
  • 如果项目不属于 BODDY,则添加当前内容,包括外部标签

let items = document.querySelectorAll('p, h3, h4');
let output = '';
items.forEach(item => {
let content = item.innerHTML.trim();
if(content.length > 0) {
output += 'n';
output += (item.parentNode.tagName == 'BODY') ? content : item.outerHTML;
}
});
console.log(output);
<ul>
<li><p>hello1</p></li>
<li><p>hello2</p></li>
</ul>
<h3> <strong>hello3</strong> </h3>
<h4> <strong><hello4></strong> </h3>
<hr>
<p> <a href="sth">sth</a> </p>

输出:

<p>hello1</p>
<p>hello2</p>
<strong>hello3</strong>
<strong><hello4></hello4></strong>
<a href="sth">sth</a>

现在您可以添加更多代码来处理<hello4></hello4>

使用 g 标志解决。似乎抓住了大多数情况。

function getFirstLine(txt) {
if (txt) {
txt = txt.trim();
const reEachLine = /<(p|h[0-9]*)>(.*?)<(/p|/h[0-9]*)>/g;
const reInnerText = /<[^>]*>([sS]*)</[^>]*>/;
const m = txt.match(reEachLine);
if (m) {
for (let i = 0; i < m.length; i += 1) {
const innerText = m[i].trim().match(reInnerText);
if (innerText) {
if (!isAllWhiteSpace(innerText[1])) return innerText[1];
} else {
return 'error loading first line - 1'; // no innertext exists
}
}
return ''; // all white text
}
return ''; // no match for <p>, <h*>
} return ''; // txt was not string or empty
}

最新更新