【问题标题】:Detecting HTML formatted strings with regex使用正则表达式检测 HTML 格式的字符串
【发布时间】:2013-09-13 21:23:50
【问题描述】:

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

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

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

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

~^\s*<~

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

【问题讨论】:

  • 试试:/&lt;([^&gt;]+)&gt;.+?&lt;\/\1&gt;/
  • ~^(\s+)?&lt;[a-z]+.*?(&gt;.*?&lt;/[a-z]+&gt;|/&gt;)~i ?
  • 顺便说一句,您还应该考虑 &lt;?xml version="1.0"?&gt;&lt;xmltag attr="1" /&gt; 是有效的 XML。
  • @elclanrs 是否解决了前面的空格?
  • @dev-null-dweller 是的。我试过了,但如果主题包含嵌套的 XML 标记,它就不起作用。

标签: php html xml regex tags


【解决方案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. 字符将包含换行符
  • m 表示PCRE_MULTILINE,匹配整个文本,不将每一行视为自己的字符串

顺便说一句:

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

【讨论】:

  • 非常感谢您指出修饰符...我不想提出这个问题,但是,假设我需要它来处理 HTML doctype 或 XML 标头(如前所述),那么?除了正则表达式之外,还有更好的方法吗?
  • @CodeCavalier 我想这取决于您的目标以及您需要什么样的accuracy - 如果您说它是 HTML,您是否需要 100% 确定它实际上是 HTML?还是您只需要为每个人分配最佳猜测?如果两者看起来都像(即其中带有 JS 的 HTML 或带有 HTML 的 JS)怎么办?如果您需要 100% 的精度,您可以为每种语言使用解析器。另一方面,如果您需要一个最佳猜测,您可以稍微放宽规则并寻找提示(格式良好的标签或 JSON 结构将是一个好的开始)。
  • @CodeCavalier 请记住,有太多的边缘情况很难做到完美,因此您需要弄清楚哪些权衡是可以接受的。例如,以// &lt;html&gt;&lt;/html&gt; 开头的JS 文件或以&lt;html&gt;&lt;!-- { ... } 开头的HTML 文件呢?
  • @CodeCavalier 我输入了所有内容,然后我刚刚阅读了您关于不想将内容添加到不匹配格式的评论。首先,应该很容易判断文件是否为 CSV。检查每一行是否存在逗号(如果它不止一列)。如果它不包含任何 HTML 标签等,您也可以假设它是 CSV 或 JSON。最后,唯一真正正确的方法是首先跟踪格式。你有机会做到吗?
猜你喜欢
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 2017-10-01
  • 2012-08-16
  • 1970-01-01
  • 2010-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多