Ruby - 替换中间行中的字符?

标签 ruby regex

嗨,我正在阅读一本有关 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/

相关文章:

Java,正则表达式捕获带有空格的字符串

r - 如何计算有多少子字符串与列表中的至少一个元素匹配,前提是它们前面或后面没有否定?

ruby-on-rails - StatementInvalid SQLite3::SQLException:没有这样的列。将标签系统添加到博客时

ruby - 为什么 const_missing 不在其前面加上 Object 就不能工作?

ruby - 测试本地套接字文件是否存在(即/tmp/mysql.sock)?

javascript - 正则表达式 JavaScript : Match consecutive single line comments

Spark SQL 中的 SQL LIKE

Ruby Gems 问题:未初始化的常量 Gem::GemRunner

ruby - 我安装了一个 gem 但 require 'gemname' 不起作用。为什么?

python - 在多页表中查找页数