2016-03-29 3 views
2

Я хочу удалить все префикс имен. (например, проф., д-р, г-н и т. д.), который может быть более одного в любой последовательности. Поэтому я хочу написать регулярное выражение, которое будет slice всех этих префиксов. Я хочу сделать это в ruby.ruby ​​regex для нескольких слов условно соответствует

Ниже приведены набор ввода/вывода, который я хочу достичь.

"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" => "" 
+1

Не просто размывайте его с помощью «и т. д.». Четко определите, к каким префиксам вы относитесь. – sawa

+1

@sawa может n нет. префиксов, все они не могут быть упомянуты, поэтому рассмотрим массив. – Datt

+0

Как вы можете удалить то, что вы не можете упомянуть? – sawa

ответ

3

Предполагая, что префиксы только Prof., Dr., Mr., Mrs., Prin., Ms. вы можете попробовать:

s = "Prof. Dr. John Doe" 
s.gsub(/Prof.|Dr.|Mr.|Mrs.|Prin.|Ms./, "").strip 

Для второго вопроса (хочу для хранения удаленных префиксов в другой строке)

s = "Prof. Dr. John Doe" 
s.scan(/Prof.|Dr.|Mr.|Mrs.|Prin.|Ms./).join("") 
=> "Prof.Dr." 
+0

Я также хочу сохранить удаленные префиксы в другой строке. – Datt

+1

Доктор Дре полностью исчезает. – steenslag

+0

Предположим, что 'name # =>« John Doe »' возвращается в первой части. Затем для второй части 's [0, s.size-name.size] .rstrip # =>« Prof. Dr. »'. –

0

Используйте этот код:

"Dr. Prin. Gloria Smith".split(". ").last 
"Prof. Dr. John Doe".split(". ").last 
+1

В некоторых случаях это не сработает. Имя может быть «Gloria A. Smith» – Datt

1

Поскольку вы просили регулярное выражение:

str = "Prof. Dr. John Doe" 
str.remove(/((Dr|Mr|Prof|Prin)\.? ?)/i) 

Это приведет:

"John Doe" 

Это будет совпадать с или без периода (Dr или Dr.) Кроме того, ' i 'в конце сделает его совпадением с нижним регистром «dr» и «prof».

+2

@RajarshiDas Похож на метод Rails, для которого OP отмечен. – sawa

+0

ooh yes correct –

3

Случай 1: список названий дается

Пусть выполнено

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, чтобы узнать, как он используется.

Случай 2: нет список названий

Далее предполагается, что все названия одного слова, начинающиеся с заглавной буквы, а затем один или несколько строчных букв, за которым следует период. Если это неверно, соответствующее регулярное выражение может быть соответствующим образом изменено.

Единственное различие между этим случаем и предыдущим состоит в том, что регулярное выражение изменяется.

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.", ""] 

Примечание: Я упростил свой первоначальный ответ.

+0

Я чувствую, что это лучший ответ. Большое использование Regex. – MTarantini

0

Если есть точка (.) После префикса, то вы можете использовать приведенную ниже логику

s = "Prof. Dr. John Doe" 
match = s.match(/([\w\s\.]+\.)?\s*([\w\s]+)/) 
prefix = match[1] 
name = match[2] 

ИЛИ

, если вы должны были иметь словарь всех префиксов

s = "Prof. Dr. John Doe" 
dictionary = ['Prof\.', 'Dr\.', 'Mr\.', 'Mrs\.', 'Prin\.'].join('|\s*') 
match = s.match(/((?:#{dictionary})*)\s*([\w\s\.]+)/) 
prefix = match[1] 
name = match[2] 

, как вы можете увидеть в приведенном выше массиве (словарь) префиксы имеют точку (.), которую вытеснили, поскольку точка (.) в регулярном выражении имеет другое значение, то есть ее метасимвол, который представляет любой символ. http://www.regular-expressions.info/dot.html

+0

@ Датта дайте мне знать, если какое-либо уточнение необходимо для того, что означает регулярное выражение –

Смежные вопросы