2

我正在尝试从一个字符串对象构建一个正则表达式,该对象恰好存储在一个变量中。

我面临的问题是转义序列(在字符串中)这样的“\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"
4

2 回答 2

4

问题是,您最终会得到完全不同的字符串,具体取决于您使用的是单引号还是双引号:

"\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有趣。(见文档

如果您遇到进一步的转义问题(使用斜杠),您还可以使用替代的 Regexp 文字语法 with %r{<your regex here>},其中您不需要转义/字符。例如:

%r{/}
#=> /\//

\不过,用转义反斜杠是没有办法的\\

于 2012-11-06T15:07:43.203 回答
0

要么用单引号创建你的字符串:

 s = '\d'
 r = Regexp.new(s)

或引用反斜杠:

 s = "\\d"
 r = Regexp.new(s)

两者都应该工作。

于 2012-11-06T14:11:32.623 回答