【问题标题】:Regex: How to replace all characters except a word/sequence of pattern?正则表达式:如何替换除单词/模式序列之外的所有字符?
【发布时间】:2017-07-07 09:41:50
【问题描述】:

我有以下字符串:

"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 作为回报。

【问题讨论】:

  • 你试过了吗?
  • 我尝试使用gsub,但无法匹配除模式之外的所有字符。
  • 请贴出你试过的代码。
  • gsub(/(?&lt;=ft-\d\s).*/) 是我天真的尝试。
  • 可以,但gsub 需要更换部件。

标签: ruby regex regex-lookarounds


【解决方案1】:

您的(?&lt;=ft-\d\s).* 模式匹配任何以ft-&lt;digits&gt;&lt;whitespace&gt; 开头的位置,然后匹配除您titleize 的换行符以外的任何0+ 字符。

您需要匹配不以ft-&lt;NUMBER&gt; 模式开头的整个单词。那么你所需要的就是将匹配小写并将其大写:

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) - 如果接下来的 2 个字母是 ft 且后跟 - 和一个数字,则匹配失败的负前瞻
  • (\p{L}+) - 匹配 1+ 个字母的捕获组(稍后在替换块中使用 $1 引用)

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

【讨论】:

  • 是否可以用\b 将其余部分作为一个句子而不是单个单词? titleize gem 处理像and、of、in 等小词,如果它们位于句子的中间。对于“ft-5 MY AWESOME APP OF RAILS ft-20”,我想获得“ft-5 My Awesome App of Rails ft-20”。这里of如果位于单词集合的中间,则由titleize gem处理。
  • 恐怕您需要在负前瞻中处理它们。喜欢\b(?!ft-\d|(?:off?|in(?:to)?|at)\b)
【解决方案2】:
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" 

【讨论】:

    【解决方案3】:

    我不是 100% 确定你想要什么,但我认为你想要小写然后标题化一个字符串

    我的一个项目中有类似的东西

    #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。默认情况下,该参数为 真的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-20
      • 2014-04-01
      • 2017-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多