字符类中的范围乱序

时间:2010-08-11 06:56:17

标签: php regex

我在preg_match()函数中遇到了这个奇怪的错误:

警告:preg_match():编译失败:偏移54处的字符类中的范围乱序

造成这种情况的一行是:

preg_match("/<!--GSM\sPER\sNUMBER\s-\s$gsmNumber\s-\sSTART-->(.*)<!--GSM\sPER\sNUMBER\s-\s$gsmNumber\s-\sEND-->/s", $fileData, $matches);

这个正则表达式的作用是解析HTML文件,只提取之间的部分:

<!--GSM PER NUMBER - 5550101 - START-->

<!--GSM PER NUMBER - 5550101 - END-->

您是否有可能导致此错误的提示?

7 个答案:

答案 0 :(得分:66)

嗨我得到了同样的错误并解决了它:

  Warning: preg_match(): Compilation failed: range out of order in character class at offset <N>

研究阶段:

..范围无序.. 因此定义了一个无法使用的范围。

..在抵消N .. 我快速查看了我的正则表达式模式。位置N是“ - ”。它用于定义“a-z”或“0-9”等范围。

解决方案

我只是逃过了“ - ”。

 \-    

现在它被解释为字符“ - ”而不是范围!

答案 1 :(得分:9)

此错误是由于范围不正确造成的。例如:9-0 a-Z 要纠正此问题,您必须将9-0更改为0-9,将a-Z更改为a-zA-Z 在你的情况下,你没有逃避角色&#34; - &#34;,然后,preg_match尝试解析正则表达式并以不正确的范围失败。 逃离&#34; - &#34;它必须解决你的问题。

答案 2 :(得分:7)

如果$gsmNumber包含方括号,反斜杠或其他各种特殊字符,则可能会触发此错误。如果可能的话,您可能需要验证这一点,以确保它在此之前确实是一个数字。

编辑2016:

有一个PHP函数可以转义正则表达式中的特殊字符:preg_quote()

像这样使用:

preg_match(
  '/<!--GSM\sPER\sNUMBER\s-\s' .
  preg_quote($gsmNumber, '/') . '\s-\sSTART-->(.*)<!--GSM\sPER\sNUMBER\s-\s' .
  preg_quote($gsmNumber, '/') . '\s-\sEND-->/s', $fileData, $matches);

显然在这种情况下,因为您使用了两次相同的字符串,您可以先将引用版本分配给变量并重新使用它。

答案 3 :(得分:4)

我收到此错误的时间如下:

[/-.]

只需将.移至开头即可解决问题:

[./-]

答案 4 :(得分:3)

虽然其他答案都是正确的,但我很惊讶地发现,在正则表达式中使用变量之前,没有人建议使用preg_quote()转义该变量。因此,如果您希望匹配实际括号或其他任何正则表达式中的内容,那么它将被转换为文字标记:

$escaped = preg_quote($gsmNumber);
preg_match( '/<!--GSM\sPER\sNUMBER\s-\s'.$escaped.'\s-\sSTART-->(.*)<!--GSM\sPER\sNUMBER\s-\s'.$escaped.'\s-\sEND-->/s', $fileData, $matches);

答案 5 :(得分:0)

您可能会让人们插入包含+, - ,(和/或)字符的手机号码,并且只是在preg_match中使用这些号码,因此您可能需要在使用之前清理所提供的数据(即通过剥离这些字符)完全出去了。

答案 6 :(得分:0)

这是几个PHP版本中的一个错误,因为我刚刚验证了当前的5.3.5版本,与Windows XP家庭版上的XAMPP 1.7.4打包在一起。

即使是一些非常简单的例子也会出现问题,例如

    $pattern = '/^[\w_-. ]+$/';
    $uid = 'guest';
    if (preg_match($pattern, $uid)) echo 
      ("<style> p { text-decoration:line-through } </style>");

PHP人员已经知道自2010年1月10日以来的错误。 见http://pear.php.net/bugs/bug.php?id=18182。 该错误被标记为“已关闭”但仍然存在。