我正在尝试从XHTML文档中检索其内容的特定标签,但它与错误的结尾标签匹配。

在以下内容中:

<cache_namespace name="content">
    <content_block id="15">
    some content here

        <cache_namespace name="user">
            <content_block id="welcome">
            Welcome Apikot!
            </content_block>
        </cache_namespace>
    </content_block>
</cache_namespace>

ID =“欢迎”的Content_Block结束标签实际上与第一个打开content_block标签的结尾标签相匹配。

我正在使用的正则是:

/<content_block id="(.*)">([\w\W]*?)<\/content_block>/i

关于我失败的地方有任何指示吗?

有帮助吗?

解决方案

…答案总是相同的: HTML +不可能完成. 。对不起。使用HTML解析库进行特定框架。或者,如果保证您的文档仅包含有效的XHTML,请在评论中按照抖动提出的XPATH方法。

其他提示

这可能有助于我找到教程 http://www.regular-expressions.info/examples.html其中提到给定文本中捕获一对弦。建议使用?之后。

这是Regex的已知问题 - 您无法匹配对。匹配要么是贪婪的,其中它与它所找到的最后一个或非怪兽匹配,其中它与第一个匹配。您不能说服正则货币符合打开和关闭的括号。

我建议将其加载到DOM中并使用它。如果您想实现HTML解析器,我建议使用Regex将其示意一下,然后使用左右解析器来解析Lexer的输出。

谢谢 @jan×科夫斯基@ikegami, ,他们的答案给了我unippiration

让我使用PHP演示代码

<?php
$xml = <<<EOT
<cache_namespace name="content">
    <content_block id="15">
    some content here

        <cache_namespace name="user">
            <content_block id="welcome">
            Welcome Apikot!
            </content_block>
        </cache_namespace>
    </content_block>
</cache_namespace>
EOT;

preg_match('/<cache_namespace[^>]+>((?:(?!(<\/?div>)).)*)<\/cache_namespace>/s', $xml, $matches);
print_r($matches);

正则注释

  • s 选项: . 在模式中与所有字符匹配,包括新线
  • 这里的关键是 (?:(?!STRING).)* 是字符串 [^CHAR]* 是字符

结果

Array
(
    [0] => <cache_namespace name="content">
    <content_block id="15">
    some content here

        <cache_namespace name="user">
            <content_block id="welcome">
            Welcome Apikot!
            </content_block>
        </cache_namespace>
    </content_block>
</cache_namespace>
    [1] => 
    <content_block id="15">
    some content here

        <cache_namespace name="user">
            <content_block id="welcome">
            Welcome Apikot!
            </content_block>
        </cache_namespace>
    </content_block>

)

解析XHTML或XML并不难。我以为您有有效或形成良好的代码。

#!/usr/bin/perl
use strict;
use warnings;
use v5.10;
my $xml = <<"EOF";
<cache_namespace name="content">
    <content_block id="15">
    some content here

        <cache_namespace name="user">
            <content_block id="welcome">
            Welcome Apikot!
            </content_block>
        </cache_namespace>
    </content_block>
</cache_namespace>
EOF

while ($xml =~ m!
<(content_block)\sid="welcome"> # Start tag definition.
 (\s*                           # It may consists of
   (?: <\!--.*?-->              # - comment
   |  [^<]*                     # - text
   |  <[^>]+/>                  # - another closed tag
   |  <\s*(\w+)[^>]*>           # - another tag with some content
       (?2)+                    # (recursive definition of possible tag content)
      </\3>
   )
 )*
</\1>
!sxgc) {
    print "==> $&\n\n";
}

请修改另一个内容的启动标签定义(例如 <\s*(\w+)[^>]*+>)。无论如何,这是一个很好的起点。

如果您不使用递归(与 (?2)+)你会坚持下去 这样的例子. 。此代码可以处理所有(请查看 这里 之前)或可以轻松适应新情况。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top