正则表达式 - 将html元素与多行上的子元素相匹配

时间:2016-01-08 16:52:53

标签: javascript html regex node.js

我有一段简单的HTML代码。

<tr>
OtherElement
</tr>
<tr>
HelloWorld
</tr>

我需要匹配包含HelloWorld的<tr></tr>元素。 我正在使用这个正则表达式,但它也匹配第一个元素。

<tr[\s\S]*?HelloWorld[\s\S]*?<\/tr>

我正在使用Node.js所以我不能使用后面的看法。

3 个答案:

答案 0 :(得分:1)

正则表达式中出现错误。这个字符集过于宽松:[\s\S]*?

尝试以下方法:

<tr>\s*HelloWorld\s*<\/tr>

\s*表示0个或更多空格字符,不包含任何其他内容。

您可能想要了解为何使用RegEx来解析HTML。这对于处理已知HTML的字符串片段(例如来自数据库)是一种有用的方法,但在JavaScript中,您最好使用XML解析器或DOM查询选择器方法。

答案 1 :(得分:1)

不要使用regexps解析HTML。相反,使用DOM例程和属性:

function find_hello_world() {
  var trs = document.querySelectorAll('tr');

  for (var i=0; i<trs.length; i++) 
    if (trs[i].textContent === "HelloWorld") return trs[i];

}

答案 2 :(得分:1)

我假设您收到HTML片段作为字符串。因此,您需要使用DOM解析器解析它(在用另一个自定义名称替换所有tr标记之后,否则解析将失败)并仅获取包含(不等于)字符串的tr个元素HelloWorld

var $txt = "<tr>\nOtherElement\n</tr>\n<tr>Initial text\nHelloWorld\nSome other text</tr>";
var $el = document.createElement( 'body' );
$el.innerHTML = $txt.replace(/<(\/?)tr\b([^<]*)>/g, "<$1tablerows$2>"); // normalize TR tags as tablerows tags
var $arr = [];
[].forEach.call($el.getElementsByTagName("tablerows"), function(v,i,a) {
    if (v.innerText.indexOf("HelloWorld") > -1) {
		$arr.push(v.innerText);
    }
});
document.write(JSON.stringify($arr, 0, 4));

正则表达式解决方案是令人讨厌和脆弱的,但可能:

<tr\b[^<]*>[^<]*(?:<(?!tr\b)[^<]*)*HelloWorld[^<]*(?:<(?!\/tr>)[^<]*)*<\/tr>

请参阅regex demo

正则表达式使用展开循环技术来匹配最接近的子模式。

  • <tr\b[^<]*> - 匹配开场TR标记
  • [^<]*(?:<(?!tr\b)[^<]*)* - 匹配除<tr以外的所有内容
  • HelloWorld - 文字序列
  • [^<]*(?:<(?!\/tr>)[^<]*)* - 除了关闭</tr>
  • 之外的所有内容
  • <\/tr> - 关闭TR标记