嗨,我正在阅读一本有关 Ruby 的教科书,发现我可以使用
.sub(/^../,'hello')
.sub(/..$/,'hello')
替换第一行中的第一个或最后两个字符。
我想知道如果有多行,如何在其他行中替换一些内容。
例如。
x = <<end_string
aaa
bbb
ccc
ddd
end_string
将“bb”更改为“某事”或将“cc”更改为某事。
当我尝试时
.sub(/\n^../,'hello')
结果是;
aaaHellob
ccc
ddd
它更改了第二行中的前两个字符,但不知何故第二行被移动到了第一行。
所以我的问题是,如何更改(替换)某一行中的字符? 如果您能解释为什么我得到这个结果,我将非常感激。
谢谢。
最佳答案
你得到这个结果是因为 sub
替换它匹配的字符串。由于您匹配了换行符(并且在替换文本中没有使用换行符),因此您的字符串随后的换行符较少。
简单的解决方案是在替换文本中使用换行符:
irb> puts x.gsub(/\n../, "\nHELLO")
aaa
HELLOb
HELLOc
HELLOd
#=> nil
如果不想对最后一行进行操作,可以使用负前瞻:
irb> puts x.gsub(/\n..(?!.*\Z)/, "\nHELLO")
aaa
HELLOb
HELLOc
ddd
#=> nil
您可以使用正向查找来避免在替换字符串中使用换行符
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 之后的任何位置
关于Ruby - 替换中间行中的字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20778120/