Ruby正则表达式保留模式的第一个实例,并替换/删除其余实例

Ruby正则表达式保留模式的第一个实例,并替换/删除其余实例,ruby,regex,Ruby,Regex,我有一个字符串,它反复包含某个单词模式。如何保留第一个引用,如果是特定情况,如何删除,如果是特定情况,如何替换模式的其余部分 rocket = "Meowth, that's right!!! Prepare for trouble meowth, and make it double. MEOWTH ftw!!!" 我想保留“meowth”的第一个实例,不区分大小写。其余的“meowth”实例:如果拼写为all caps,则将替换为字符串“team rocket”。除此之外,它将被移除 ro

我有一个字符串,它反复包含某个单词模式。如何保留第一个引用,如果是特定情况,如何删除,如果是特定情况,如何替换模式的其余部分

rocket = "Meowth, that's right!!! Prepare for trouble meowth, and make it double. MEOWTH ftw!!!"
我想保留
“meowth”
的第一个实例,不区分大小写。其余的
“meowth”
实例:如果拼写为all caps,则将替换为字符串
“team rocket”
。除此之外,它将被移除

rocket.gsub(/meowth/i, 'team rocket') 
上面的代码替换所有
“meowth”
字符串实例(不区分大小写)。如何保留第一个实例并替换/删除其余实例

期望输出:

rocket = "Meowth, that's right!!! Prepare for trouble, and make it double. team rocket ftw!!!"

如果第一次出现在字符串的开头,您可以在模式的开头使用负向前看
(?!\a)
或向后看
(?)来排除字符串开头的匹配项:

rocket = "Meowth, that's right!!! Prepare for trouble meowth, and make it double. MEOWTH ftw!!!"
rocket.gsub(/(?!\A)\s*(meowth)/i) { $1.upcase == $1 ? ' team rocket' : '' }
# => Meowth, that's right!!! Prepare for trouble, and make it double. team rocket ftw!!!

如果单词的第一个实例可以位于字符串中的任何位置,而不仅仅是字符串的开头,请使用

rocket.gsub(/(?:\G(?!\A)|\A.*?meowth).*?\K\s*(meowth)/mi) { 
          $1.upcase == $1 ? ' team rocket' : '' 
}

注意:要将
meowth
作为一个整体匹配,请用单词边界将其括起来:
/(?!\a)\s*\b(meowth)\b/

详细信息

  • (?!\A)
    -在当前位置,字符串不应有开头
  • \s*
    -0+空格
  • (喵喵叫)
    -第1组捕获
    喵喵叫
    (由于
    /i
    修饰语,不区分大小写)
或者

  • (?:\G(?!\A)|\A.*meowth)
    -在成功匹配(
    \G(?!\A)
    )或从字符串开始(
    \A
    )到第一次出现
    meowth
    (如
    *?
    尽可能少地匹配任何0+字符)后匹配位置
  • *?
    -任何0+字符尽可能少,直到第一个字符
  • \K
    -省略匹配的文本
  • \s*
    -0+空格
  • (喵喵)
    -
    喵喵
    (第1组)

在块内部,使用
.upcase
检查捕获的值是否为ALLCAPS,如果是,则将该值替换为
团队火箭
,esle,removed。

如果第一次出现在字符串的开头,则可以使用负的前向
(?!\a)
或后向
(?在模式的开头,以排除字符串开头的匹配项:

rocket = "Meowth, that's right!!! Prepare for trouble meowth, and make it double. MEOWTH ftw!!!"
rocket.gsub(/(?!\A)\s*(meowth)/i) { $1.upcase == $1 ? ' team rocket' : '' }
# => Meowth, that's right!!! Prepare for trouble, and make it double. team rocket ftw!!!

如果单词的第一个实例可以位于字符串中的任何位置,而不仅仅是字符串的开头,请使用

rocket.gsub(/(?:\G(?!\A)|\A.*?meowth).*?\K\s*(meowth)/mi) { 
          $1.upcase == $1 ? ' team rocket' : '' 
}

注意:要将
meowth
作为一个整体匹配,请用单词边界将其括起来:
/(?!\a)\s*\b(meowth)\b/

详细信息

  • (?!\A)
    -在当前位置,字符串不应有开头
  • \s*
    -0+空格
  • (喵喵叫)
    -第1组捕获
    喵喵叫
    (由于
    /i
    修饰语,不区分大小写)
或者

  • (?:\G(?!\A)|\A.*meowth)
    -在成功匹配(
    \G(?!\A)
    )或从字符串开始(
    \A
    )到第一次出现
    meowth
    (如
    *?
    尽可能少地匹配任何0+字符)后匹配位置
  • *?
    -任何0+字符尽可能少,直到第一个字符
  • \K
    -省略匹配的文本
  • \s*
    -0+空格
  • (喵喵)
    -
    喵喵
    (第1组)

在块内部,使用
.upcase
检查捕获的值是否为ALLCAPS,如果是,则将该值替换为
team rocket
,esle,removed。

您不需要复杂的正则表达式,只需传递一个块:

str.gsub(/meowth/i).with_index do |w, i|
  if i != 0 && w == 'MEOWTH'
    w = 'team rocket'
  elsif i != 0
    w = ''
  end

  w
end

您不需要复杂的正则表达式,只需传递一个块:

str.gsub(/meowth/i).with_index do |w, i|
  if i != 0 && w == 'MEOWTH'
    w = 'team rocket'
  elsif i != 0
    w = ''
  end

  w
end

第一个实例总是在字符串的开头吗?正确。很抱歉,我不清楚。第一个实例表示任何时候您看到
“meowth”
在字符串中首先出现(不区分大小写),即使拼写为MEOWTH,如果是first,则保持原样。替换/删除发生在第一次出现之后。第一个实例是否始终位于字符串的开头?正确。很抱歉,我不清楚。first-instance表示任何时候看到
“MEOWTH”
在字符串中首先出现(不区分大小写),即使拼写为MEOWTH,如果是第一个,也保持原样。替换/删除发生在第一次出现之后。如果您想知道如果不是在字符串开头,是否可以使用纯正则表达式解决方案替换第二次出现的单词,请参阅。嗨,Wiktor!感谢您的快速响应,但是如何删除非所有大写字母?我的如果不清楚,请道歉。只有
MEOWTH
会被
team rocket
替换;除第一次以外的任何其他MEOWTH事件:MEOWTH、MEOWTH、MEOWTH和c。这不全是大写(MEOWTH)需要删除。请参阅所需的输出。谢谢!在您的情况下,您有
为故障做好准备火箭队,以及…
,我如何才能让它
为故障做好准备,以及…
。这难道不要求第一个
meowth
也是第一个单词吗?以防您怀疑是否可以使用纯正则表达式解决方案来替换单词从第二次出现开始,如果不是在字符串开头,请参见。您好,Wiktor!感谢您的快速响应,但是我如何才能删除非所有的大写字母?如果不清楚,我深表歉意。只有
MEOWTH
team rocket
替换;除了第一次以外的任何其他MEOWTH事件:MEOWTH,MEOWTH,MEOWTH,&c。这不全是c需要删除AP(MEOWTH)。请参阅所需的输出。谢谢!在您的情况下,您有
为故障做好准备火箭队,以及…
,我如何才能使它
为故障做好准备,以及…
。这不需要第一个
MEOWTH
作为我们的第一个单词吗