14

我的代码中有一个正则表达式,它匹配 url 的模式并抛出错误:

/^(http|https):\/\/([\w-]+\.)+[\w-]+([\w- .\/?%&=]*)?$/

错误是“char 类错误中的空范围”。我发现这是([\w- .\/?%&=]*)?部分原因。Ruby 似乎将-in识别\w- .为 range 而不是文字的运算符-。在破折号中添加转义后,问题就解决了。

但原来的正则表达式在我同事的机器上运行良好。我们使用相同版本的 osx、rails 和 ruby​​:Ruby 版本是 ruby​​ 1.9.3p194,rails 是 3.1.6,osx 是 10.7.5。在我们将代码部署到我们的 Heroku 服务器之后,一切都运行良好。为什么只有我的环境对此正则表达式有错误?Ruby regex 解释的机制是什么?

4

1 回答 1

18

我可以在使用 rvm 1.13.4 安装在 Ubuntu 12.04.1 LTS 上的 Ruby 1.9.3p194(2012-04-20 修订版 35410)[i686-linux] 上复制此错误。但是,这不应该是特定于版本的错误。事实上,我很惊讶它完全可以在其他机器上运行。

一个同样失败的简单演示:

"abcd" =~ /[\w- ]/

这是因为[\w- ]它被解释为“以空格(或空白)之前的任何单词字符开头的范围”,而不是包含单词、连字符或空格的字符类,这正是您想要的。

根据 Ruby 的正则表达式文档

在字符类中,连字符 (-) 是表示包含字符范围的元字符。[abcd] 等价于 [ad]。一个范围后面可以跟另一个范围,所以 [abcdwxyz] 等价于 [a-dw-z]。范围或单个字符出现在字符类中的顺序无关紧要。

如您所见,在反斜杠前面添加了连字符,从而将正则表达式的性质从范围更改为字符类,从而消除了错误。但是,不建议在字符类中间转义连字符,因为在这种情况下很容易混淆连字符的预期含义。正如 m.buettner 指出的那样,始终将连字符放在字符类的开头或结尾:

"abcd" =~ /[-\w ]/
于 2012-11-08T08:57:29.457 回答