ruby-on-rails - 用于多个单词的 ruby​​ 正则表达式有条件地匹配

标签 ruby-on-rails ruby regex

我想删除名称的所有前缀。 (例如,Prof.、Dr.、Mr. 等)可以在任何序列中超过一个。所以我想写一个正则表达式来 slice 所有这些前缀。我想在 ruby 中执行此操作。

以下是我要实现的输入/输出集。

"Prof. Dr. John Doe" => "John Doe"
"Dr. Prin. Gloria Smith" => "Gloria Smith"
"Dr. William" => "William"
"Sean Paul" => "Sean Paul"

我还想将删除的前缀存储在另一个字符串中。

"Prof. Dr. John Doe" => "Prof. Dr."
"Dr. Prin. Gloria Smith" => "Dr. Prin."
"Dr. William" => "Dr."
"Sean Paul" => ""

最佳答案

情况一:给定标题列表

假设

titles = ["Dr.", "Prof.", "Mr.", "Mrs.", "Ms.", "Her Worship", "The Grand Poobah"]

R = /
    (?:   # begin non-capture group
      #{Regexp.union(titles)}
          # "or" all the titles
      \s* # match >= 0 spaces
    )*    # end non-capture group and perform >= 0 times
    /x    # free-spacing regex definition mode
  #=> /
  #   (?:   # begin non-capture group
  #     (?-mix:Dr\.|Prof\.|Mr\.|Mrs\.|Ms\.|Her\ Worship|The\ Grand\ Poobah)
  #         # "or" all the titles
  #     \s* # match >= 0 spaces
  #   )*    # end non-capture group and perform >= 0 times
  #  /x 

def extract_titles(str)
  t = str[R] || ''
  [str[t.size..-1], t.rstrip] 
end

["Prof. Dr. John J. Doe, Jr.", "Dr. Prin. Gloria Smith", "The Grand Poobah Dr. No",
  "Gloria Smith", "Cher, Ph.D."].each { |s| p extract_titles s }
  # ["John J. Doe, Jr.", "Prof. Dr."]
  # ["Prin. Gloria Smith", "Dr."]
  # ["No", "The Grand Poobah Dr."]
  # ["Gloria Smith", ""]
  # ["Cher, Ph.D.", ""]

如果没有标题,如上两个例子,str[R] => nil,所以(str[R] || "").rstrip #=> "".rstrip #=> "".

请参阅类方法的文档 Regexp::union看看它是如何使用的。

情况二:没有标题列表

以下假定所有标题都是一个单词,以大写字母开头,后跟一个或多个小写字母,再后跟一个句点。如果不正确,可以相应地更改下面的正则表达式。

这种情况与前一种情况的唯一区别是正则表达式发生了变化。

R = /
    \A       # match beginning of string
    (?:      # start a non-capture group
      [A-Z]  # match a capital letter
      [a-z]+ # match > 0 lower-case letters
      \.\s*  # match a period followed by >= 0 spaces
    )*       # end non-capture group and execute >= 0 times
    /x       # free-spacing regex definition mode

["Prof. Dr. John J. Doe, Jr.", "Dr.Prin.Gloria Smith",
 "Gloria Smith", "Cher, Ph.D."].each { |s| p extract_titles(s) }
  # ["John J. Doe, Jr.", "Prof. Dr."]
  # ["Gloria Smith", "Dr. Prin."]
  # ["Gloria Smith", ""]
  # ["Cher, Ph.D.", ""]

关于ruby-on-rails - 用于多个单词的 ruby​​ 正则表达式有条件地匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36287306/

相关文章:

ruby-on-rails - 如何允许用户嵌入 YouTube 和 Vimeo 视频?

正则表达式。匹配模式后如何从结果中排除子字符串

ruby-on-rails - 使用书面记录,了解与 object_changes 的区别?

ruby-on-rails - Rails 4 will_paginate articles/post by tags

ruby-on-rails - 如何使用 rspec 测试模型上没有修改任何属性?

ruby - 在非 ruby​​ 项目中使用 rake

ruby-on-rails - Devise 和 ActionMailer 混淆

javascript - 任何人都知道像 Readability 这样工作的 ruby​​ 库吗?

javascript - 用逗号分割字符串,但在 JavaScript 中不进行转义

php - JavaScript 正则表达式不适用于 PHP