正则表达式:如何替换除了单词/模式序列之外的所有字符?

时间:2017-02-17 18:33:41

标签: ruby regex regex-lookarounds

我有以下字符串:

"ft-2 MY AWESOME ft-12 APP"
"MY AWESOME APP"
"MY AWESOME APP ft-20"

我希望对除ft-<NUMBER>部分之外的字词进行一些修改(在本例中为titleization)。 ft-<NUMBER>字可以出现在任何地方。它可以出现多次,也可能根本不出现。字符串操作后,最终结果应如下所示:

"ft-2 My Awesome ft-12 App"
"My Awesome App"
"My Awesome App ft-20"

是否有可能在Ruby中编写任何可以进行此转换的正则表达式?

我试过这样:

"ft-4 MY AWESOME ft-5 APP".gsub(/(?<=ft-\d\s).*/) { |s| s.titleize }

我得到了这个:ft-4 My Awesome Ft 5 App作为回报。

3 个答案:

答案 0 :(得分:4)

R = /
    [[:alpha:]]+ # match one or more uppercase or lowercase letters
    (?=\s|\z)    # match a whitespace or end of string (positive lookahead)
    /x           # free-spacing regex definition mode

def doit(str)
  str.gsub(R) { |s| s.capitalize }
end

doit "ft-2 MY AWESOME ft-12 APP"
  #=> "ft-2 My Awesome ft-12 App" 
doit "MY AWESOME APP"
  #=> "My Awesome App" 
doit "MY AWESOME APP ft-20"
  #=> "My Awesome App ft-20" 

答案 1 :(得分:1)

您的(?<=ft-\d\s).*模式与ft-<digits><whitespace>之前的任何位置匹配,然后匹配除titleize的换行符之外的任何0 +字符。

您需要匹配不以ft-<NUMBER>模式开头的整个单词。然后你需要的只是将比赛缩小并将其大写:

s.gsub(/\b(?!ft-\d)\p{L}+/) { | m | m.capitalize }

或者,如果您更喜欢使用$1变量,请添加捕获组:

s.gsub(/\b(?!ft-\d)(\p{L}+)/) { $1.capitalize }

请参阅Ruby demo

模式详情

  • \b - 首先,在一封信之前断言位置(因为下一个消费模式是\p{L}与一封信相匹配)
  • (?!ft-\d) - 如果接下来的两个字母ft后跟-和数字
  • ,则会导致匹配失败的否定前瞻
  • (\p{L}+) - 一个匹配1+个字母的捕获组(稍后在替换块中引用$1

capitalize “返回str的副本,第一个字符转换为大写,余数为小写”

答案 2 :(得分:0)

我不是百分之百确定你想要什么,但我认为你想要做什么,然后标题化一个字符串

我的某个项目中有类似内容

#lib/core_ext/string.rb
class String
  def my_titleize
    humanize.gsub(/\b('?[a-z])/) { $1.capitalize }
  end
end
  

humanize(options = {})public将第一个单词大写,轮流   将下划线划分为空格,如果存在则删除尾随的“_id”。喜欢   titleize,这是为了创造漂亮的输出。

     

可以通过设置来关闭第一个单词的大小写   可选参数大写为false。默认情况下,此参数为   真。