我正在尝试从string对象构建正则表达式,该对象恰好存储在一个变量中。
我面临的问题是,转义的序列(在字符串中),如"\d“,不会生成最终的正则表达式。
Regexp.new("\d") => /d/
如果我使用单引号,很难,它工作得无懈可击。
Regexp.new('\d') => /\d/
但是,因为我的字符串存储在一个变量中,所以我总是得到带双引号的字符串。
有没有一种方法可以将双引号的字符串转换为单引号的字符串,以便在Regexp构造函数中使用?
(我想使用双引号的字符串插值功能)
示例:
email_pattern = "/[a-z]*\.com"
whole_pattern = "to: #{email_pattern}"
Regexp.new(whole_pattern)
为了更好的可读性,我想避免转义字符。
"\\d"
发布于 2012-11-06 23:07:43
问题是,您最终得到完全不同的字符串,这取决于您使用的是单引号还是双引号:
"\d".chars.to_a
#=> ["d"]
'\d'.chars.to_a
#=> ["\\", "d"]
因此,当您使用双引号时,单\
会立即丢失,并且无法根据定义恢复,例如:
"\d" == "d"
#=> true
因此,在转义发生之前,您永远不会知道字符串包含了什么。正如@FrankSchmitt建议的那样,使用双反斜杠或使用单引号。没有别的办法了。
不过,还是有一个选择的。您可以将正则表达式部分定义为正则表达式本身,而不是字符串。它们的行为完全符合预期:
regex1 = /\d/
#=> /\d/
regex2 = /foobar/
#=> /foobar/
然后,您可以使用#{}
-style插值构建最终的正则表达式,而不是从字符串构建正则表达式源代码:
regex3 = /#{regex1} #{regex2}/
#=> /(?-mix:\d) (?-mix:foobar)/
反映您的示例,这将转换为:
email_regex = /[a-z]*\.com/
whole_regex = /to: #{email_regex}/
#=> /to: (?-mix:[a-z]*\.com)/
您可能还会发现Regexp#escape
很有趣。(see the docs)
如果遇到进一步的转义问题(使用斜杠),您还可以将替代的Regexp文本语法与%r{<your regex here>}
一起使用,在这种语法中,您不需要转义/
字符。例如:
%r{/}
#=> /\//
不过,使用\\
来转义反斜杠\
是没有办法的。
发布于 2012-11-06 22:11:33
创建包含单引号的字符串:
s = '\d'
r = Regexp.new(s)
或者引用反斜杠:
s = "\\d"
r = Regexp.new(s)
这两种方法都应该有效。
https://stackoverflow.com/questions/13252743
复制相似问题