简体   繁体   English

字符类中的范围乱序

[英]Range out of order in character class

I'm getting this odd error in the preg_match() function:我在 preg_match() 函数中遇到了这个奇怪的错误:

Warning: preg_match(): Compilation failed: range out of order in character class at offset 54警告:preg_match():编译失败:偏移量 54 处字符类中的范围乱序

The line which is causing this is:导致这种情况的行是:

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

What this regular expression does is parse an HTML file, extracting only the part between:这个正则表达式的作用是解析一个 HTML 文件,只提取以下部分:

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

and:和:

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

Do you have a hint about what could be causing this error?您是否有关于可能导致此错误的提示?

Hi I got the same error and solved it:嗨,我遇到了同样的错误并解决了它:

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

Research Phase:研究阶段:

.. Range out of order .. So there is a range defined which can't be used. .. 范围乱序 ..所以定义了一个不能使用的范围。

.. at offset N .. I had a quick look at my regex pattern. .. 在偏移 N ..我快速查看了我的正则表达式模式。 Position N was the "-".位置 N 是“-”。 It's used to define ranges like "az" or "0-9" etc.它用于定义“az”或“0-9”等范围。

Solution解决方案

I simply escaped the "-".我只是逃避了“-”。

 \-    

Now it is interpreted as the character "-" and not as range!现在它被解释为字符“-”而不是范围!

This error is caused for an incorrect range.此错误是由不正确的范围引起的。 For example: 9-0 aZ To correct this, you must change 9-0 to 0-9 and aZ to a-zA-Z In your case you are not escaping the character "-", and then, preg_match try to parse the regex and fail with an incorrect range.例如: 9-0 aZ 要更正此问题,您必须将 9-0 更改为 0-9 并将 aZ 更改为 a-zA-Z 在您的情况下,您没有转义字符“-”,然后,preg_match 尝试解析regex 并以不正确的范围失败。 Escape the "-" and it must solve your problem.转义“-”,它必须解决您的问题。

If $gsmNumber contains a square bracket, backslash or various other special characters it might trigger this error.如果$gsmNumber包含方括号、反斜杠或各种其他特殊字符,则可能会触发此错误。 If that's possible, you might want to validate that to make sure it actually is a number before this point.如果可能,您可能需要验证它以确保它实际上是在此之前的数字。

Edit 2016: 2016年编辑:

There exists a PHP function that can escape special characters inside regular expressions: preg_quote() .有一个 PHP 函数可以对正则表达式中的特殊字符进行转义: preg_quote()

Use it like this:像这样使用它:

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);

Obviously in this case because you've used the same string twice you could assign the quoted version to a variable first and re-use that.显然,在这种情况下,因为您使用了两次相同的字符串,您可以先将引用的版本分配给变量并重新使用它。

I was receiving this error with the following sequence:我收到此错误,顺序如下:

[/-.]

Simply moving the .只需移动. to the beginning fixed the problem:一开始就解决了这个问题:

[./-]

While the other answers are correct, I'm surprised to see that no-one has suggested escaping the variable with preg_quote() before using it in a regex.虽然其他答案是正确的,但我很惊讶地看到没有人建议在正则表达式中使用变量preg_quote()之前对其进行转义。 So if you're looking to match an actual bracket or anything else that means something in regex, that'll be converted to a literal token:因此,如果您希望匹配实际的括号或任何其他在正则表达式中表示某些内容的内容,则会将其转换为文字标记:

$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);

您可能让人们插入手机号码,包括 +、-、( 和/或 ) 字符,并在 preg_match 中按原样使用它们,因此您可能希望在使用之前清理提供的数据(即通过完全去除这些字符) .

This is a bug in several versions of PHP, as I have just verified for the current 5.3.5 version, as packaged with XAMPP 1.7.4 on Windows XP home edition.这是多个版本的 PHP 中的一个错误,因为我刚刚验证了当前 5.3.5 版本,它与 Windows XP 家庭版上的 XAMPP 1.7.4 打包在一起。

Even some very simple examples exhibit the problem, eg,甚至一些非常简单的例子也表现出这个问题,例如,

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

The PHP folks have known about the bug since 1/10/2010. PHP 人员自 2010 年 1 月 10 日起就知道该错误。 See http://pear.php.net/bugs/bug.php?id=18182 .参见http://pear.php.net/bugs/bug.php?id=18182 The bug is marked "closed" yet persists.该错误被标记为“已关闭”但仍然存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM