题
我正在尝试从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)+
)你会坚持下去 这样的例子. 。此代码可以处理所有(请查看 这里 之前)或可以轻松适应新情况。
不隶属于 StackOverflow