【问题标题】:Regex to match contents of HTML body正则表达式匹配 HTML 正文的内容
【发布时间】:2009-07-30 17:07:46
【问题描述】:

编辑:哎呀,对不起,我不清楚。我有一个从 AJAX 获得的字符串,它是一个 xhtml 文档,我需要获取它的 body 标签,除非我可以从该字符串生成一个 dom 树?

我需要使用 javascript 正则表达式从字符串中的正文标记获取所有内容,包括标记。

我知道这是重复的,但我在其他问题中发现的正则表达式是针对不同风格的正则表达式的,并且给了我错误。

提前致谢。

【问题讨论】:

  • 你为什么不用 DOM 来做这个?
  • 乔治,为什么不将其发布为答案?
  • 我做了,然后删除了评论。我也很犹豫,因为(s)他说(s)他想要一个正则表达式。

标签: javascript regex


【解决方案1】:

document.getElementsByTagName('body')[0].innerHTML 将返回正文标记中所有内容的字符串。这不是一个正则表达式,但我不确定你为什么需要一个...?

发布问题编辑:

用于执行 AJAX 的 XHR 对象具有 responseTextresponseXML 属性。只要响应是有效的 xml(可能应该是),您就可以在我提到的 xml 对象上使用 getElementsByTagName 获取您想要的任何标签。但如果你只想要身体的内部,我会这样做:

var inner = myXHR.responseText.split(/(<body>|</body>)/ig)[2]);

【讨论】:

  • +1 建议采取正确的途径...我在回复中提供了为什么这是正确途径的原因。
  • @Svante:我们不要陷入理智。如果我们开始谈论这个话题,我们就会意识到你必须要疯到连看看一台该死的电脑。
  • 请注意,上面一行的正确语法是:var inner = myXHR.responseText.split(/(&lt;body&gt;|&lt;\/body&gt;)/ig)[2];
【解决方案2】:

Regex 并不是解析 DOM 的理想工具,正如您将在本网站和其他网站中看到的那样。正如 George IV 所建议的,最理想的方法是使用更适合此的 JavaScript 工具,即 getElementsByTagName 并获取 innerHTML:

var bodyText = document.getElementsByTagName("body")[0].innerHTML;

Edit1:我还没有检查过,但是 Rudisimo 建议了一个工具,它显示了一个 很多 的承诺 - XRegExp 库,它是一个开源和麻省理工学院的可扩展库。这可能是一个可行的选择——我仍然认为 DOM 是更好的方法,但这看起来比正则表达式的标准 JavaScript 实现要好得多。

Edit2:由于 Gumbo 提供的示例,我放弃了我之前关于 Regex 引擎的陈述 [出于准确性的原因] - 无论表达方式多么荒谬。但是,我确实坚持我的观点,在这种情况下使用正则表达式本质上是一种糟糕的方式,您应该使用上述示例引用 DOM。

【讨论】:

  • -1 您不需要后视断言。 JavaScript 的正则表达式有一个 i 修饰符。而. 加上s 修饰符可以替换为[\s\S][\w\W][\d\D] 等。
  • @Gumbo 你能指点我的文档来支持它吗?我过去曾遇到过这方面的问题,但我并不高兴,因为所有文档都表明并非如此。您能否发布一个 可以 工作的正则表达式,以便我对其进行测试和验证?然后我可以删除这个不准确的答案。
  • 这不是 JavaScript 正则表达式引擎的限制,而是正则表达式本身的基本限制。
  • @Svante - 我不同意,我只花了几秒钟就在 RegexBuddy 中敲出 .NET 风格的表达式,它给了我正确的信息,完全没有任何问题。如果这是一般正则表达式的固有限制,那么情况就不会如此。
【解决方案3】:

一般来说正则表达式不适合解析。但如果你真的想使用正则表达式,试试这个:

/^\s*(?:<(?:!(?:(?:--(?:[^-]+|-[^-])*--)+|\[CDATA\[(?:[^\]]+|](?:[^\]]|][^>]))*\]\]|[^<>]+)|(?!body[\s>])[a-z]+(?:\s*(?:[^<>"']+|"[^"]*"|'[^']*'))*|\/[a-z]+)\s*>|[^<]+)*\s*<body(?:\s*(?:[^<>"']+|"[^"]*"|'[^']*'))*\s*>([\s\S]+)<\/body\s*>/i

如您所见,没有简单的方法可以做到这一点。我什至不会声称这是一个正确的正则表达式。但它应该考虑注释标签(&lt;!-- … --&gt;)、CDATA 标签(&lt;![CDATA[ … ]]&gt;)和普通的 HTML 标签。

祝你阅读愉快。

【讨论】:

  • 好吧,你打败了我 - 干得好,剪切韧性 +1。不过这种表达方式很可笑。我不会向我最大的敌人推荐遍历 DOM。
【解决方案4】:

每个人似乎都对使用正则表达式死心塌地,所以我想我会走另一条路,回答你的第二个问题。

理论上可以将 AJAX 的结果解析为 xmlDocument。 如果您想让它发挥作用,您可能需要采取一些步骤。

  1. 使用库。我推荐 jQuery
  2. 如果您使用的是库,则必须确保响应的 mimetype 是 xml mimetype!
  3. 确保在所有目标浏览器中进行彻底测试。你会被绊倒的。

话虽如此,我在 jsbin 上创建了一个快速示例。 它适用于 IE 和 Firefox,不幸的是,为了让它工作,我不得不滚动我自己的 XMLHttpRequest 对象。

View the example source code here

(说真的,这段代码很难看。值得使用一个库并正确设置 mime 类型......)

function getXHR() {
    var xmlhttp;
    //Build the request
    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        // code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    } else {
        alert("Your browser does not support XMLHTTP!");
    }


    //Override the mime type for firefox so that it returns the 
    //result as an XMLDocument.
    if( xmlhttp.overrideMimeType ) {
        xmlhttp.overrideMimeType('application/xhtml+xml; charset=x-user-defined');
    }

    return xmlhttp;
}

function runVanillaAjax(url,functor)
{
    var xmlhttp = getXHR();
    xmlhttp.onreadystatechange=function() { functor(xmlhttp); };
    xmlhttp.open("GET",url,true);
    xmlhttp.send(null);
}

function vanillaAjaxDone( response ) {
    if(response.readyState==4) {

        //Get the xml document element for IE or firefox
        var xml;
        if ($.browser.msie) {
            xml = new ActiveXObject("Microsoft.XMLDOM");
            xml.async = false;
            xml.loadXML(response.responseText);
        } else {
            xml = response.responseXML.documentElement;
        }

        var textarea = document.getElementById('textarea');
        var bodyTag = xml.getElementsByTagName('body')[0];
        if( $.browser.msie ) {
            textarea.value = bodyTag.text;
        } else {
            textarea.value = bodyTag.textContent;
        }
    }
}

function vanillaAjax() {
    runVanillaAjax('http://jsbin.com/ulevu',vanillaAjaxDone);
}

【讨论】:

    【解决方案5】:

    对于 JavaScript 中 RegExp 库的 点匹配换行符 限制有一个替代修复。 XRegExp 是一个功能强大的开源库,具有几乎无限的许可证“MIT 许可证”(用于商业项目),非常紧凑(压缩后 2.7KB)且功能强大。

    如果您转到 New Flags 部分,您可以看到如何有一个标志 (s),其中 dot 匹配 所有个字符;包括换行符。

    【讨论】:

    • +1 很棒的发现!你知道它实现了什么风格的正则表达式吗?乍一看似乎很有希望。
    • 查看xregexp.com/syntax 部分。它让您了解它使用的基于其命名捕获支持的版本,这似乎是 .NET 的。
    猜你喜欢
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多