为什么这个Ruby不能像预期的那样取代正则表达式?

时间:2010-10-22 01:20:15

标签: ruby regex

考虑以下字符串,它是文件中的C片段:

strcat(errbuf,errbuftemp);

我想用前缀G->替换errbuf(但不是errbuftemp);再加上errbuf。为了成功地做到这一点,我检查后面的字符和errbuf之前的字符,看它是否在批准的字符列表中,然后我执行替换。

我创建了以下Ruby文件:

line = " strcat(errbuf,errbuftemp);"  
item = "errbuf"  
puts line.gsub(/([ \t\n\r(),\[\]]{1})#{item}([ \t\n\r(),\[\]]{1})/, "#{$1}G\->#{item}#{$2}")

预期结果:

strcat(G->errbuf,errbuftemp);

实际结果

strcatG->errbuferrbuftemp);

基本上,errbuf之前和之后的匹配字符不会重新插入替换表达式。

任何人都可以指出我做错了什么?

2 个答案:

答案 0 :(得分:3)

因为您必须使用语法gsub(/.../){"...#{$1}...#{$2}..."}gsub(/.../,'...\1...\2...')

以下是同样的问题:werid, same expression yield different value when excuting two times in irb

  

问题是变量$ 1在运行gsub之前插入到参数字符串中,这意味着$ 1的前一个值是符号被替换的值。你可以用'\ 1?'替换第二个参数。获得预期的效果。 (卡盘)

答案 1 :(得分:0)

我认为问题的一部分是使用gsub()而不是sub()。

以下是两个替补:

str = 'strcat(errbuf,errbuftemp);'

str.sub(/\w+,/) { |s| 'G->' + s } # => "strcat(G->errbuf,errbuftemp);"
str.sub(/\((\w+)\b/, '(G->\1') # => "strcat(G->errbuf,errbuftemp);"