例如:要将第一分组大写:
str = '1abc2aabbcc3aaabbbccc4'
pp str.sub(/(a{2})(b{2})/, '\1.upcase\2') # =>"1abc2aa.upcasebbcc3aaabbbccc4" 第一分组怎么没有变大写呢?
pp str.sub(/(a{2})(b{2})/, '\1'.upcase + '\2') # =>"1abc2aabbcc3aaabbbccc4" 奇怪,upcase()还是没起作用!?
pp str.sub(/(a{2})(b{2})/, $1.upcase + '\2') # =>"1abc2AAbbcc3aaabbbccc4" 使用$1而不是'\1',upcase()才起作用?
这里涉及两个问题:
1,
'\1'
和$1
, 两种反向引用的区别2, Ruby中单引号
'
和双引号"
的细微区别你可能注意到, 我写的是
'\1'
而不是\1
, 因为Ruby作为通用语言, 是不存在\1
这种对象的. 换句话说, 你是不能单独写\1
.问题1:
'\1'
用在匹配内,$1
用在匹配外.$1
本质是全局变量, 只要发生正则匹配,Ruby
就会更新这些全局变量. 此处主要是参考Perl
的正则设计.'\1'
本质是字串, 只是在匹配时, 用于组的反向引用.但在广义上,
\1
的确是正规的正则反向引用, 如在sed
中使用,echo str | sed -E 's,(a{2})(b{2}),\2\1,g'
.说明:
'\1'
表示匹配的第一组, 即a
, 意思是重复两个a
.但一个特殊处, 在执行替换时, 也可以使用
'\1'
.问题2:
大部分情况下,
'
和"
用法相同, 但在处理\
时有区别. 双引号的"\1"
是表示"\u0001"
, 也就是说, 用来键入unicode
字符, 是一个字符. 而单引号的'\1'
, 就是\
和1
, 是两个字符, 如前述, 其本质是字符串, 当执行'\1'.upcase
时, 是对两个字符执行大写, 但Ruby
中, 非小写字符的#upcase
方法返回本身.考虑你这里的意思, 应该是先将
'\1'
替换为aa
, 再执行#upcase
方法, 再替换原字串. 就我目前知道, 做不到这点, 除非ruby在语言层面提供新的语法, 否则,'\1'
就只是一个字串, 它对匹配组的引用并不是变量存储的过程, 猜测可能是, 在底层执行的过程, 会自动将'..'
中的\1
替换为引用的字串.解答:
'\1.upcase\2'
, 单引号中的'\1'
和'\1'
分别被替换为aa
和bb
,.upcase
不变.'\1'.upcase
为'\1'
, 再与'\2'
连接$1.upcase
,$1
变量存储字串'aa'
, 再大写try "\1"
参数传入方法时,是先计算参数,再把结果传入方法的