繁体   English   中英

Ruby regex保留pattern的第一个实例,并替换/删除其余的

[英]Ruby regex keep the first instance of pattern and substitute/remove the rest

我有一个重复包含某个单词模式的字符串。 我如何保留第一次出现的情况,在特定情况下将其删除,并在特定情况下替换其余模式?

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

我想保留"meowth"的第一个实例,不区分大小写。 “其余"meowth"实例的其余部分:如果将其拼写为全部大写,则将其替换为字符串"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)或后向(?<!\\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!!!

观看Ruby演示

如果单词的第一个实例可以在字符串内的任何地方,而不仅仅是在字符串的开头,请使用

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

参见另一个Ruby演示

:匹配meowth作为一个整体的话,用单词边界括起来: /(?!\\A)\\s*\\b(meowth)\\b/

详细资料

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

要么,

  • (?:\\G(?!\\A)|\\A.*?meowth) -匹配成功匹配后的位置( \\G(?!\\A) )或从字符串开头( \\A )到meowth首次出现(如.*?匹配任意0+个字符的次数越少越好
  • .*? -最多0个字符,直到第一个
  • \\K省略匹配的文本
  • \\s* -0+空格
  • (meowth) - meowth (组1)。

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

您实际上并不需要复杂的正则表达式,只需传递一个代码块即可:

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

  w
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM