2016-03-29 154 views
2

我想刪除名稱的所有前綴。 (例如,教授,博士,先生等),其可以以任何順序多於一個。所以我想寫一個正則表達式,這將所有這些前綴slice。我想在ruby中這樣做。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" => "" 
+1

不要只用「etc」模糊它。清楚說明你所關心的前綴是什麼。 – 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

Dr. Dre完全消失。 – 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'和'prof'。

+2

@RajarshiDas看起來像OP標記的Rails方法。 – sawa

+0

噢是的正確 –

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

我覺得這是一個更好的答案。大量使用正則表達式。 – MTarantini

0

如果總是有一個點(。)前綴後則可以使用下面的邏輯

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

OR

如果你是有所有前綴

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

@Datta讓我知道是否需要澄清正則表達式的意義 –