Ruby 正则表达式组替换

标签 ruby regex pattern-matching gsub

我正在尝试在 Ruby 中的同一行上执行正则表达式匹配和替换。我有一些库可以在 Ruby 中操作字符串并向其添加特殊格式字符。可以按任何顺序应用格式。但是,如果我想更改字符串格式,我想保留一些原始格式。我为此使用正则表达式。我有正确匹配我需要的正则表达式:

mystring.gsub(/[(\e\[([1-9]|[1,2,4,5,6,7,8]{2}m))|(\e\[[3,9][0-8]m)]*Text/, 'New Text')

但是,我真正想要的是来自以下位置的第一个分组的匹配:

(\e\[([1-9]|[1,2,4,5,6,7,8]{2}m))

附加到 New Text 并替换,而不是仅仅 New Text。我正在尝试以

的形式引用匹配项
mystring.gsub(/[(\e\[([1-9]|[1,2,4,5,6,7,8]{2}m))|(\e\[[3,9][0-8]m)]*Text/, '\1' + 'New Text')

但我的理解是 \1 仅在使用 \d\k 时有效。有没有办法在我的替换字符串中引用特定的捕获组?此外,由于我对 [] 使用了星号,所以我知道这种分组可能会出现不止一次。因此,我希望产生最后一个匹配项。

我对示例的预期输入/输出是:

Input:  "\e[1mHello there\e[34m\e[40mText\e[0m\e[0m\e[22m"
Output: "\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m"

Input:  "\e[1mHello there\e[44m\e[34m\e[40mText\e[0m\e[0m\e[22m"
Output: "\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m"

因此找到并追加了最后一个分组。

最佳答案

您可以在替换中使用以下带有反向引用 \\1 的正则表达式:

reg = /(\\e\[(?:[0-9]{1,2}|[3,9][0-8])m)+Text/
mystring = "\\e[1mHello there\\e[34m\\e[40mText\\e[0m\\e[0m\\e[22m"
puts mystring.gsub(reg, '\\1New Text')

mystring = "\\e[1mHello there\\e[44m\\e[34m\\e[40mText\\e[0m\\e[0m\\e[22m"
puts mystring.gsub(reg, '\\1New Text')

IDEONE demo 的输出:

\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m
\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m

请注意,您的输入有反斜杠 \ 需要在常规字符串文字中转义。为了在正则表达式中匹配它,我们使用双斜杠,因为我们正在寻找文字反斜杠。

关于Ruby 正则表达式组替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30223232/

相关文章:

php - 正则表达式 X/Y 坐标

PHP 用 URL 替换字符串中的模式

error-handling - 如何减少处理多行结果返回错误的代码

linux - 在 bash 中将文本 append 到具有模式匹配名称的文件

ruby-on-rails - 用 Ruby 写一个 mp4 文件

java - Apache NiFi 中的 ReplaceText 用法

ruby-on-rails - Rails 中自定义验证器中的 http 请求

java - 为什么这个模式不匹配? ([\\\\A\\\\W]其[\\\\W\\\\z])

ruby - 在 Chef Recipe 中干燥

ruby-on-rails - 如何通过 factorygirl 中的特征将属性传递给关联?