使用正则表达式检测HTML格式的字符串

时间:2013-09-13 21:23:50

标签: php html xml regex tags

我正在尝试检测字符串是XML / HTML格式,还是其他格式,如CSV或JSON,可能包含HTML作为数据,或者只是一般文本,可能包含随机<或者>字符。我不是要验证完整的XML或HTML文档 - 我正在测试的字符串可能只是XML / HTML的片段,或者它们可能是其他内容的片段。因此,我的标准是字符串必须包含至少一个格式正确的XML标记,并且该标记必须从字符串的开头开始,禁止任何空格。 (此时,您可能已经猜到我正在尝试自动检测mime类型的文本内容,然后再将其发送回浏览器。顺便说一下,我是在PHP中。)

我有一个将检测XML / HTML标记的正则表达式:

~<[a-z]+.*?(>.*?</[a-z]+>|/>)~i

我有一个正则表达式告诉我标签是否启动字符串,忽略空格:

~^\s*<~

问题是,我无法弄清楚如何将这两者合并为一个正则表达式。困难似乎源于正则表达式的“贪婪”方面,特别是如果主题包含嵌套标签。帮助

1 个答案:

答案 0 :(得分:1)

以下示例似乎对我有用:

<?php

$multiline = <<<'EOD'
<html>
<a>Another Tag</a>
</html>
EOD;

$singletag = <<<'EOD'
<html/>
EOD;


$badformat = <<<'EOD'
<html><html>
EOD;

$nothtml = <<<'EOD'
<html><html>
EOD;

$regex = '~^\s*<([a-z\:]+)[^>]*(?:/>|>.*</\1>)~sim';
echo preg_match($regex, $multiline) . "\n"; // 1
echo preg_match($regex, $singletag) . "\n"; // 1
echo preg_match($regex, $badformat) . "\n"; // 0
echo preg_match($regex, $nothtml) . "\n"; // 0

如果您在多行HTML上使用此功能(听起来很可能),则您没有正确的modifiers

  • s PCRE_DOTALL.字符将包含换行符
  • 对于PCRE_MULTILINE
  • m ,匹配整篇文章,不将每一行视为自己的字符串

顺便说一下:

  • 我也更加严格,因此必须找到匹配的结束标记(使用\1反向引用)
  • HTML / XML文档还有其他有效的开头,如评论中所述(例如HTML doctype或XML标题)。正则表达式可能不是最佳解决方案。
  • 您还可以考虑在文件开头要求标记时不要太严格,或者为“最佳猜测”文档类型创建进一步的分数规则。