反斜杠+;Ruby正则表达式中捕获的组
如何在捕获的组之前删除反斜杠 例如:反斜杠+;Ruby正则表达式中捕获的组,ruby,regex,Ruby,Regex,如何在捕获的组之前删除反斜杠 例如: "foo+bar".gsub(/(\+)/, '\\\1') 我所期望的(和想要的): 我不幸得到的是: foo\\1bar 如何在这里正确转义?再添加两次\将正确转义 irb(main):011:0> puts "foo+bar".gsub(/(\+)/, '\\\\\1') foo\+bar => nil 这是由于双字符串转义造成的。在这种情况下,您应该使用5个斜杠 "foo+bar".gsub(/([+])/, '\\\\\1')
"foo+bar".gsub(/(\+)/, '\\\1')
我所期望的(和想要的):
我不幸得到的是:
foo\\1bar
如何在这里正确转义?再添加两次
\
将正确转义
irb(main):011:0> puts "foo+bar".gsub(/(\+)/, '\\\\\1')
foo\+bar
=> nil
这是由于双字符串转义造成的。在这种情况下,您应该使用5个斜杠
"foo+bar".gsub(/([+])/, '\\\\\1')
正如其他人所说的那样,你需要两次逃避这个字符串中的所有内容。因此,在您的案例中,解决方案是使用
'\1'
或'\1'
。但既然你问了为什么,我就试着解释一下
原因是替换序列被解析了两次——一次由Ruby解析,一次由底层正则表达式引擎解析,\1
是它自己的转义序列。(使用双引号字符串可能更容易理解,因为单引号会引入歧义,其中'\\1'
和'\1'
是等效的,但'\'
和'\\'
不是。)
例如,这里用一个捕获的组和一个双引号字符串进行简单替换:
"foo+bar".gsub(/(\+)/, "\\1") #=> "foo+bar"
这将字符串\1
传递给regexp引擎,它将其理解为对捕获组的引用。在Ruby字符串文本中,“\1”
表示完全不同的含义(ASCII字符1)
在这种情况下,我们实际上希望regexp引擎接收\\\1
。它还将\
理解为转义字符,因此\\1
是不够的,只需计算文本输出\1
。因此,我们需要在regexp引擎中使用\\\1
,但要达到这一点,我们还需要让它通过Ruby的字符串文本解析器
为此,我们获取所需的regexp输入并再次加倍每个反斜杠,以通过Ruby的字符串文本解析器<代码>\\\1因此需要“\1”
。在单引号的情况下,可以省略一个斜杠,因为\1
在单引号中不是有效的转义序列,而是按字面处理的
补遗
这个问题通常被隐藏的原因之一是由于使用了/.+/
风格的regexp引号,Ruby以一种特殊的方式处理它,以避免双重转义。(当然,这不适用于gsub
替换字符串。)但如果在regexp.new
中使用字符串文字而不是regexp文字,您仍然可以看到它的作用:
Regexp.new("\.").match("a") #=> #<MatchData "a">
Regexp.new("\\.").match("a") #=> nil
Regexp.new(“\”).match(“a”)#=>#
Regexp.new(“\\”).match(“a”)\=>nil
如您所见,我们必须对
进行双重转义,才能让regexp引擎将其理解为文本
,因为“
和”\。
在双引号字符串中计算为
,但是我们需要引擎本身来接收\。
你能解释一下这里发生了什么,为什么需要5个吗?这个让我抓狂!
Regexp.new("\.").match("a") #=> #<MatchData "a">
Regexp.new("\\.").match("a") #=> nil