使用正则表达式从HTML中提取文本和链接

时间:2010-01-02 11:30:18

标签: html regex regex-negation

我想从html文档中提取文本,保留其中的链接。例如:

来自此HTML代码

<div class="CssClass21">bla1 bla1 bla1 <a href="http://www.ibrii.com">go to ibrii</a> bla2 bla2 bla2 <img src="http://www.contoso.com/hello.jpg"> <span class="cssClass34">hello hello</span>

我想提取这个

bla1 bla1 bla1 <a href="http://www.ibrii.com">go to ibrii</a> bla2 bla2 bla2 hello hello

在StackOverflow的另一篇文章中,我找到了RegEx <[^>]*>,它允许通过替换每个匹配来提取文本。如何从匹配中排除锚标记?似乎RegEx不允许反向匹配。

2 个答案:

答案 0 :(得分:2)

正则表达式确实允许通过lookahead进行非平凡的否定形式,但在这种情况下,作为一个练习会很好,因为,虽然每次regexp被提及时我都没有狂热的圣火与HTML一起,这确实是一个需要解析器解决的问题。

答案 1 :(得分:0)

暂时将<a href ...>...</a>编码为其他内容,删除所有其他代码,然后恢复<a>代码:

// Example in javascript:
string.
    replace(/<a(.*?)>/g,'\0$1\0').
    replace(/<\/a>/,'\1').
    replace(/<[^>]*>/,'').
    replace(/\0(.*?)\0/,'<a$1>').
    replace(/\1/,'</a>');

在上面的代码中,我使用NUL和SOH字符(ASCII 0x00和0x01)作为<a>标记的替换,因为它们不太可能出现在字符串中。您可以随意将其替换为字符串中不会出现的任何其他字符或字符序列。

根据其他评论,您似乎在浏览器中操作。在这种情况下,浏览器已经将HTML解析为一个漂亮的DOM树。使用DOM方法解析树并按照您希望的方式处理它:

function simpleHTML (domNode) {
    var ret = "";
    if (domNode.nodeType === Node.ELEMENT_NODE) {
        var children = domNode.childNodes;
        for (var i=0;i<children.length;i++) {
            var child = children[i];

            // Filter out unwanted nodes to speed up processing.
            // For example, you can ignore 'SCRIPT' nodes etc.
            if (child.nodeName != 'SCRIPT') {
                if (child.nodeName == 'A') {
                    ret += '<a href="' + child.href + '">' +
                               simpleHTML(child) +
                           '</a>';
                }
                else {
                    ret += simpleHTML(child);
                }
            }
        }
    }
    else if (domNode.nodeType === Node.TEXT_NODE) {
        ret +=  domNode.nodeValue;
    }
    return ret;
}
// serialize the whole document:
var simpleDocument = simpleHTML(document.body);

// serialize a div:
var simpleDiv = simpleHTML(document.getElementById('some_div'));

// filter a html formatted string:
var temp = document.createElement('DIV');
temp.innerHTML = original_string;
simple_string = simpleHTML(temp);