正则表达式-如何查找未包含在html标记中或它们之间的单词

问题描述

|| 我想在html字符串中找到匹配项。 那不会在html标记之间或它们内部。 例如: 这个词是:
ue
<span color=blue>ue</span>ue<span>sdfsd</span>
所以我只想找到第三个匹配项(不在\“ blue \”内部),而不是在
span
标记之间。 谢谢     

解决方法

        您正在尝试使用正则表达式来解析HTML。 HTML本身无法使用正则表达式轻松,可靠地进行处理。 如果您是在浏览器上执行此操作,则可以改用浏览器的高度优化的HTML解析器。 如果您想在中间有一个标签(例如\“ u
e \”)时检测到该单词,请执行以下操作:
var element,node,topLevelText;
element = document.createElement(\'div\');
element.innerHTML = \"<span color=blue>ue</span>ue<span>sdfsd</span>\";
topLevelText = \"\";
for (node = element.firstChild; node; node = node.nextSibling) {
    if (node.nodeType === 3) { // 3 = text node
        topLevelText += node.nodeValue;
    }
}
if (topLevelText.indexOf(word) >= 0) {
    // Found
}
如果您只想在事物之间检测到它(因此,您的示例而不是\“ u
e \”):
var element,node;
element = document.createElement(\'div\');
element.innerHTML = \"<span color=blue>ue</span>ue<span>sdfsd</span>\";
for (node = element.firstChild; node; node = node.nextSibling) {
    if (node.nodeType === 3) { // 3 = text node
        if (node.nodeValue.indexOf(word) >= 0) {
            // Found
        }
    }
}
(两者都区分大小写。) 就是这样 使用
document.createElement
创建不会在任何地方显示的元素。 通过将HTML文本分配给元素上的
innerHTML
来解析HTML文本。该属性直到最近才被标准化,但是十年来,所有主流浏览器都支持该属性。 浏览该节点的直接子节点,该子节点将包含通过解析创建的所有元素,以及字符串中顶级文本(例如,您要搜索的地方的文本)的文本节点。这是使用
Node#firstChild
Node#nodeType
Node#nodeValue
Node#nextSibling
。 根据您是否要在“ u
e \”情况下找到它,它要么直接查看每个文本节点中的文本,要么将它们全部构建为一个字符串,然后进行搜索。 上面的链接主要针对DOM2 Core规范,大多数浏览器都支持其中的大多数规范。其他方便的参考资料: DOM2 HTML规范(HTML特定的DOM内容) DOM3核心规范(更新的DOM内容)     ,        假设您要处理的是HTML片段(而不是完整的文档),则可以编写一个正则表达式以匹配格式最完整的内部非嵌套元素,然后递归应用此正则表达式删除所有标记的材料,从而保留标签之间剩余的所需非标签材料。这就是这样的正则表达式(以注释的PHP / PCRE \'x \'语法),与大多数空和非空,非嵌套,非短标签HTML元素匹配。
$re_html = \'%# Match non-nested,non-shorttag HTML empty and non-empty elements.
    <                    # Opening tag opening \"<\" delimiter.
    (\\w+)\\b              # $1: Tag name.
    (?:                  # Non-capture group for optional attribute(s).
      \\s+                # Attributes must be separated by whitespace.
      [\\w\\-.:]+          # Attribute name is required for attr=value pair.
      (?:                # Non-capture group for optional attribute value.
        \\s*=\\s*          # Name and value separated by \"=\" and optional ws.
        (?:              # Non-capture group for attrib value alternatives.
          \"[^\"]*\"        # Double quoted string.
        | \\\'[^\\\']*\\\'     # Single quoted string.
        | [\\w\\-.:]+\\b    # Non-quoted attrib value can be A-Z0-9-._:
        )                # End of attribute value alternatives.
      )?                 # Attribute value is optional.
    )*                   # Allow zero or more attribute=value pairs
    \\s*                  # Whitespace is allowed before closing delimiter.
    (?:                  # This element is either empty or has close tag.
      />                 # Is either an empty tag having no contents,| >                  # or has both opening and closing tags.
      (                  # $2: Tag contents.
        [^<]*            # Everything up to next tag. (normal*)
        (?:              # We found a tag (open or close).
          (?!</?\\1\\b) <  # Not us? Match the \"<\". (special)
          [^<]*          # More of everything up to next tag. (normal*)
        )*               # Unroll-the-loop. (special normal*)*
      )                  # End $2. Tag contents.
      </\\1\\s*>           # Closing tag.
    )
    %x\';
这是Javascript语法中的同一个正则表达式:
var re_html = /<(\\w+)\\b(?:\\s+[\\w\\-.:]+(?:\\s*=\\s*(?:\"[^\"]*\"|\'[^\']*\'|[\\w\\-.:]+\\b))?)*\\s*(?:\\/>|>([^<]*(?:(?!<\\/?\\1\\b)<[^<]*)*)<\\/\\1\\s*>)/;
以下javascript函数剥离HTML元素,从而在标签之间保留所需的文本:
// Strip HTML elements.
function strip_html_elements(text) {
    // Match non-nested,non-shorttag HTML empty and non-empty elements.
    var re = /<(\\w+)\\b(?:\\s+[\\w\\-.:]+(?:\\s*=\\s*(?:\"[^\"]*\"|\'[^\']*\'|[\\w\\-.:]+\\b))?)*\\s*(?:\\/>|>([^<]*(?:(?!<\\/?\\1\\b)<[^<]*)*)<\\/\\1\\s*>)/g;
    // Loop removing innermost HTML elements from inside out.
    while (text.search(re) !== -1) {
        text = text.replace(re,\'\');
    }
    return text;
}
此正则表达式解决方案不是正确的解析器,仅处理仅包含html元素的简单HTML片段。它不能(也不能)正确处理具有注释,CDATA节和doctype语句之类的更复杂的标记。它不会删除缺少其可选的close标签的元素(即
<p>
<li>
元素。)     ,        HTML不是一种常规语言,因此无法通过正则表达式进行解析。     ,        由于您在浏览器中具有出色的DOM操作可能性,因此可以利用它。您可以创建一个新元素,将字符串设置为content并遍历所有文本节点:
var tmp = document.createElement(\'div\');
tmp.innerHTML = htmlString;

var matches = [],children = tmp.childNodes,word = \' \' + word + \' \';

for(var i = children.length; i--; ) {
    node = children[i];
    if(node.nodeType === 3 && (\' \' + node.nodeValue + \' \').indexOf(word) > -1) {
        matches.push(node);
    }
}