您好我正在阅读有关Ruby的教科书,并发现我可以使用
.sub(/^../,'hello')
.sub(/..$/,'hello')
替换第一行中的第一个或最后两个字符。
我想知道如果有多行,我怎么能用其他行代替。
例如
x = <<end_string
aaa
bbb
ccc
ddd
end_string
将'bb'更改为'某事'或'cc'。
当我尝试
时.sub(/\n^../,'hello')
结果是;
aaaHellob
ccc
ddd
更改了第二行中的前两个字符,但不知何故,第二行被移动到第一行。
所以我的问题是,如何更改(替换)某一行中的字符? 如果你能解释我为什么得到这个结果,我会非常感激。
谢谢。
答案 0 :(得分:2)
你得到了那个结果,因为sub
替换了它匹配的字符串。由于您匹配换行符(并且未在替换文本中使用换行符),因此您的字符串之后的换行符较少。
简单的解决方案是在替换文本中使用换行符:
irb> puts x.gsub(/\n../, "\nHELLO")
aaa
HELLOb
HELLOc
HELLOd
#=> nil
如果您不想在最后一行操作,可以使用否定前瞻:
irb> puts x.gsub(/\n..(?!.*\Z)/, "\nHELLO")
aaa
HELLOb
HELLOc
ddd
#=> nil
您可以使用正面的lookbehind来避免在替换字符串中使用换行符
irb> puts x.gsub(/(?<=\n)..(?!.*\Z)/, "HELLO")
aaa
HELLOb
HELLOc
ddd
#=> nil
lookahead和lookbehinds的语法有点奇怪,但它们只是将模式(匹配并消耗一些文本长度)转换为与文本中零宽度位置匹配的东西。在正则表达式中已经有零宽度位置匹配,使用:
^
作为行首$
代表行\b
用于字边界\A
表示字符串的开头\Z
结束字符串Lookaheads和lookbehinds让你自己定义:
(?=PAT)
〜在PAT (?<=PAT)
〜在PAT (?!PAT)
〜匹配任何地方,但在PAT (?<!PAT)
〜匹配任何地方,但在PAT 答案 1 :(得分:0)
分割线,替换特定线和连接线怎么样?
>> x = <<end_string
aaa
bbb
ccc
ddd
end_string
>> lines = x.split("\n")
>> lines[1].sub!(/../, 'hello')
>> lines = lines.join("\n")
>> puts lines
aaa
hellob
ccc
ddd