字符串#gsub中我的\ +发生了什么?

时间:2013-05-25 17:47:23

标签: ruby regex

在Ruby脚本中,我使用string#gsub生成一个用作正则表达式的字符串。此正则表达式必须与+字符匹配,因此我使用\+来逃避它。

此示例代码隔离了我的混淆源。在此代码中,我要创建的正则表达式是/a\+b/。但是,当我使用#gsub时,返回的正则表达式为/ab/

string = 'a\+b'
expected = Regexp.new(string)
actual = Regexp.new('x'.gsub('x', string))

# expected returns /a\+b/
# actual returns /ab/

我在Ruby文档中找不到关于#gsub+字符的任何内容。任何人都可以帮助我理解产生这种结果的情况吗?

现在,为了使我的代码工作,我匹配\x2B+字符的ANSI十六进制代码。有没有办法实现这个没有被混淆的东西?

提前致谢!

4 个答案:

答案 0 :(得分:3)

我们忽略这里的Regexp.new,因为它不是真正相关的 - 只有gsub本身。

\+gsub解释为\\d的反向引用。来自the docs

  

如果replacement是一个String,它将替换匹配的文本。它可能包含对d形式的模式捕获组的反向引用,其中\\k<n>是组号,或n,其中$&是组名。如果它是双引号字符串,则两个反向引用都必须以额外的反斜杠开头。但是,在替换中,特殊匹配变量(例如\+)不会引用当前匹配。

虽然不是很清楚(因为文档说“group number ”),$+将替换全局变量$+ *;来自Ruby Quickref

  

$~:取决于'x'.gsub(/(x)/, 'a\+b') #=> "axb" 。最高组与上一次成功比赛匹配。

我们可以通过捕捉东西证明这一点:

\+

这表明"ab"正在被正则表达式中的捕获所取代。由于您的模式中没有捕获(因为它是一个字符串),因此后引用将替换为空字符串,并且gsub会得到"a\+b"

使用\+可以正常工作,因为它实际上不是"a\+b".bytes #=> [97, 43, 98] 'a\+b'.bytes #=> [97, 92, 43, 98]

gsub

*有点,它在语义上是等价的,但是匹配全局变量本身实际上并没有设置,直到 {{1}}完成替换后 - 但是后引用是,当然,在更换之前设置。

答案 1 :(得分:1)

替换字符串\+内部用于指代最后一个捕获组的值(例如,如果正则表达式包括3个捕获组\+,则与{{1}相同})。如果您使用\3的块形式,则不会执行这些替换:

gsub

答案 2 :(得分:0)

Regexp的union方法通常用于从字符串(和/或Regexps)的组合创建正则表达式。因为它逃脱了这些字符串,所以它也很有用:

re = Regexp.union("a+b") # => /a\+b/ 

答案 3 :(得分:-1)

Regexp.new会自动处理+

试试这个:

string = 'a+b'
expected = Regexp.new(string)
actual = Regexp.new('x'.gsub('x', string))

如果您有其他意思,请告诉我

对你问题的另一种解释让我想到了这一点:

string = 'a\\\+b'
expected = Regexp.new(string)
actual = Regexp.new('x'.gsub('x', string))