前言:我知道反对使用 regex 解析HTML的普遍共识。提前询问,请避免在这方面提出任何建议。
我有以下正则表达式
/<div class="panel-body">([^]*?)(<\/div>|$)/gi
它匹配div
内的所有内容,包括自我,内容为.panel-body
完全匹配:
<div class="panel-body">
<a href="#">Link</a>
Line 1
Line 2
Line 3
</div>
..它还匹配没有结束div
标记的内容。
完全匹配:
<div class="panel-body">
<a href="#">Link</a>
Line 1
Line 2
Line 3
Don't match after closing `div`...but match this and below in case closing `div` is removed.
Line below 1
Line below 2
Line below 3
如何改进我的正则表达式以执行以下操作:
不包含在完整匹配<div class="panel-body">
和结束</div>
(当有结束div
标记时)
直接(如果可能)直接进入完全匹配而不使用群组
字符串不以<div class="panel-body">
开头,而是以
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webmin 1.851 on centos.centos (CentOS Linux 7.3.1611)</title>
</head>
<body>
<div>
<div>
<div class="panel-body">
* 注意:它在完全加载之前从不关闭,因为它是渐进式输出。
在发布答案后,我进行了速度比较测试。这取决于你,他的解决方案最适合你。
Speed-test Results答案 0 :(得分:3)
您可以使用DOM
解析器,该解析器也应包含不完整的标记:
function divContent(str) {
// create a new dov container
var div = document.createElement('div');
// assign your HTML to div's innerHTML
div.innerHTML = '<html>' + str + '</html>';
// find an element by given className
var el = div.getElementsByClassName("panel-body");
// return found element's first innerHTML
return (el.length > 0 ? el[el.length-1].innerHTML : "");
}
// extract text from a complete tag:
var html = `<div class="panel-body">
<a href="#">Link</a>
Line 1
Line 2
Line 3
</div>`;
console.log(divContent(html));
// extract text from an incomplete tag:
html = `<div class="panel-body">
<a href="#">Link</a>
Line 1
Line 2
Line 3
Don't match after closing 'div'...but match this and below
in case closing 'div' is removed.
Line below 1
Line below 2
Line below 3`;
console.log(divContent(html));
// OP'e edited HTML text
html = `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webmin 1.851 on centos.centos (CentOS Linux 7.3.1611)</title>
</head>
<body>
<div>
<div>
<div class="panel-body">`;
console.log(divContent(html));
&#13;
答案 1 :(得分:2)
我无法评论,所以我会尝试一个答案。如何非捕获组,你仍然在完全匹配,但你唯一的匹配条目将是内容。索引0。
(?:<div class="panel-body">)([^]*?)(?:<\/div>|$)
答案 2 :(得分:2)
它必须是正则表达式吗?您可以只查找开始标记,并可选择删除结束标记(如果存在):
function parseContent(input) {
var openingTag = '<div class="panel-body">';
var i = input.indexOf(openingTag);
if (i == -1) {
return ""; // Or something else
}
var closingTag = '</div>';
var closingTagLength = closingTag.length;
var end = input.length - (input.slice(-closingTagLength) === closingTag ? closingTagLength : 0);
return input.slice(i + openingTag.length, end);
}
编辑:
如果结束标记后面有文字,那么也只需使用indexOf
:
function parseContent(input) {
var openingTag = '<div class="panel-body">';
var i = input.indexOf(openingTag);
if (i == -1) {
return ""; // Or something else
}
var closingTag = '</div>';
var endIndex = input.indexOf(closingTag, i);
var end = (endIndex === -1 ? input.length : endIndex);
return input.slice(i + openingTag.length, end);
}
答案 3 :(得分:1)
如果无标记,您可以使用 - 所有行都不以&lt;开头字符
(^|\r|\n|\r\n)[^<]+
具体示例获取第一行
\<[^div] ([^\r\n]*\n)+
如果您需要将最后一个字符结束后还有其他行:
\<[^div] ([^\r\n]*\n)+Line 3