Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 被一个简单的正则表达式难住了_Ruby_Regex - Fatal编程技术网

Ruby 被一个简单的正则表达式难住了

Ruby 被一个简单的正则表达式难住了,ruby,regex,Ruby,Regex,我试图查看字符串s是否包含正则表达式中的任何符号。下面的正则表达式在上运行良好 但在Ruby 1.9.2中,它给出了以下错误消息: syntax error, unexpected ']', expecting tCOLON2 or '[' or '.' s = "asd#d"; s =~ /[~!@#$%^&*()]/ 怎么了?我能够在1.9.3p0中复制这种行为。显然“#$”组合有问题。如果你逃走了,它就会起作用。如果您将其反转,则会起作用: s =~ /[~!@$#%^&

我试图查看字符串
s
是否包含正则表达式中的任何符号。下面的正则表达式在上运行良好

但在Ruby 1.9.2中,它给出了以下错误消息:

syntax error, unexpected ']', expecting tCOLON2 or '[' or '.'
s = "asd#d"; s =~ /[~!@#$%^&*()]/

怎么了?

我能够在1.9.3p0中复制这种行为。显然“#$”组合有问题。如果你逃走了,它就会起作用。如果您将其反转,则会起作用:

s =~ /[~!@$#%^&*()]+/

编辑:在Ruby 1.9中,
#$
调用变量插值,即使后面跟一个不是有效变量名的
%

我不同意,您需要转义$,它是字符串的结尾

s =~ /[~!@#\$%^&*()]/ => 3

这是正确的。

这实际上是字符串插值的一个特例,其中包含大多数人似乎不知道的全局变量和实例变量。由于Ruby中的正则表达式中也存在字符串插值,因此我将在下面用字符串进行说明(因为它们提供了一个更简单的示例):

因此,您需要对
#
进行转义,以防止其被插值:

/[~!@\#$%^&*()]+/
据我所知,在Ruby中创建非插值正则表达式的唯一方法是从字符串(注意单引号):


我在rubular mysqlf上试过。似乎只有
#
匹配。这就是你的rubular所显示的吗?@junky:对我来说,使用
a$d#d
$
在rubular上都是匹配的。实际上,
是需要转义的。
$
在这里没有特殊意义,因为它位于组
[]
内。从技术上讲,在字符类之外,它是行尾(而不是字符串)。但是,它在character class.Hmm中失去了任何特殊意义。关于你的更新,是的,颠倒了这两个工作。太奇怪了。是的,我无法解释为什么即使选择了1.9.2,它也能在rubular上运行。@MarkThomas也许rubular使用了
Regexp.new(“…”)
?他们没有真正的理由接受插值,因为没有变量,如果有什么的话,这可能也是一个安全问题。嘎!你似乎是对的!哦,Ruby,为什么要插入我的正则表达式?这很奇怪,因为
$%
不是一个有效的全局变量,所以我认为不会调用插值。@Zabba我用一种方法更新了我的答案,创建了一个非插值的正则表达式,但遗憾的是,似乎没有一种更简洁的方法,即字符串的单引号。@MarkThomas同意,语法错误似乎没有很好地暗示这一点,但是
/$%/
也会导致语法错误。这似乎真的混淆了解析器。为了将来的参考,这是至少一本书中记录的行为:
@foo = "instancefoo"
$foo = "globalfoo"
"#@foo" # => "instancefoo"
"#$foo" # => "globalfoo"
/[~!@\#$%^&*()]+/
Regexp.new('[~!@#$%^&*()]+')