好吧,我知道有几个类似的问题,但在这个特定案例中找不到任何问题。
我使用了一段代码并根据需要对其进行了调整,但现在我在其中发现了一个我无法纠正的错误。
代码:
$tag = 'namespace';
$match = Tags::get($f, $tag);
var_dump($match);
static function get( $xml, $tag) { // http://stackoverflow.com/questions/3404433/get-content-within-a-html-tag-using-7-processing
// bug case string(56) "<namespaces>
// <namespace key="-2">Media</namespace>"
$tag_ini = "<{$tag}[^\>]*?>"; $tag_end = "<\\/{$tag}>";
$tag_regex = '/' . $tag_ini . '(.*?)' . $tag_end . '/si';
preg_match_all($tag_regex,
$xml,
$matches,
PREG_OFFSET_CAPTURE);
return $matches;
}
如你所见,如果标签是嵌套的,就会出现错误:
<namespaces> <namespace key="-2">Media</namespace>
什么时候应该返回'Media',甚至是外层的'<namespaces>'
然后是里面的。
我尝试添加“<{$tag}[^\>|^\r\n ]*?>
”,^\s+
,将 * 更改为 *?,以及其他一些在最好的情况下只能识别错误情况的事情。
也试过"<{$tag}[^{$tag}]*?>"
这给出了空白,我想它会自行无效。
我是正则表达式的新手,我可以说要解决这个问题只需要添加不要让打开相同类型的新标签。 或者我什至可以为我的用例使用 hack 答案,排除内部文本是否有换行符。
谁能得到正确的语法?
您可以在此处查看文本摘录:http://pastebin.com/f2naN2S3
提议的更改后:$tag_ini = "<{$tag}\\b[^>]*>"; $tag_end = "<\\/{$tag}>";
它确实适用于示例案例,但不适用于此案例:
<namespace key="0" />
<namespace key="1">Talk</namespace>
因为它导致:
<namespace key="1">Talk"
这是因为数字和 "以及字母被认为是在单词边界内。我该如何解决这个问题?
最佳答案
主要问题是您没有在开始标记后使用单词边界,因此,namespace
在模式中也可以匹配 namespaces
标记和许多其他标记。
后续问题是 <${tag}\b[^>]*>(.*?)<\/${tag}>
如果有一个自动关闭模式会过火 namespace
标签后跟“正常”成对打开/关闭 namespace
标签。因此,您需要使用负面回顾 (?<!\/)
在 >
之前(参见 demo ),或使用 (?![^>]*\/>)
\b
之后的负前瞻(参见 demo)。
所以,你可以使用
$tag_ini = "<{$tag}\\b[^>]*(?<!\\/)>"; $tag_end = "<\\/{$tag}>";
关于php - preg 匹配标签之间的文本,排除之间的相同标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37512370/