【问题标题】:Replace all non capitalised words with ruby用 ruby​​ 替换所有非大写单词
【发布时间】:2017-05-25 01:00:24
【问题描述】:

我想用“-”替换文本中所有非大写的单词。单词的长度。

例如,我有以下文本(德语):

Florian Homm 饰演 Sohn des mittelständischen Handwerksunternehmers Joachim Homm 和 seiner Frau Maria-Barbara “Uschi” Homm im hessischen Bad Homburg vor der Höhe auf。 Sein Großonkel mütterlicherseits war der Unternehmer Josef Neckermann。 Nach einem Studium an der Harvard, das er mit einem Master of Business Administration and der Harvard Business School abschloss, 在美国-amerikanischen Finanzwirtschaft bei der Investmentbank Merrill Lynch 开始 Homm seine Tätigkeit, danach war er bei dem US-Fondsanbieter Fidelity Investments, der Schweizer Privatbank Julius Bär und dem US-Vermögensverwalter Tweedy Browne....

应该变成

Florian Homm ---- --- Sohn --- ------------ Handwerksunternehmers Joachim Homm --- ------ Frau Maria-Barbara “Uschi” Homm -- ---------- 巴特洪堡 --- Höhe ---。 ....

【问题讨论】:

  • 如果你不能完成你自己的例子,它可能太长了。
  • „word“ 呢?

标签: ruby text replace capitalize


【解决方案1】:

解决方案

这个问题比看起来更难!

这段代码可能比其他代码更需要内存,但我敢说它适用于更广泛的(奇怪的)德语单词:

def hide_non_capitalized(text)
  text.split(/[[:space:]]/).map do |chars|
    first_letter = chars[/[[:alpha:]]/]
    if first_letter && first_letter == first_letter.downcase
      ## Keep non-letters :
      chars.gsub(/[[:alpha:]]/,'-')
      ## Replace every character :
      # '-' * chars.size
    else
      chars
    end
  end.join(' ')
end

它将文本分割成字符块,如果第一个字母是小写,则替换块中的所有字母。此代码需要 Ruby 2.4,因为在 Ruby 2.3 之前,'ä'.upcase 仍然是 'ä'

测试

puts hide_non_capitalized(text)
#=> Florian Homm ----- --- Sohn --- ----------------- Handwerksunternehmers Joachim Homm --- ------ Frau Maria-Barbara „Uschi“ Homm -- ---------- Bad Homburg --- --- Höhe ---. Sein Großonkel ----------------- --- --- Unternehmer Josef Neckermann. Nach ----- Studium -- --- Harvard University, --- -- --- ----- Master -- Business Administration -- --- Harvard Business School ---------, ------ Homm ----- Tätigkeit -- --- US-amerikanischen Finanzwirtschaft --- --- Investmentbank Merrill Lynch, ------ --- -- --- --- US-Fondsanbieter Fidelity Investments, --- Schweizer Privatbank Julius Bär --- --- US-Vermögensverwalter Tweedy Browne....

hide_none = "Änderung. „Uschi“, Attaché-case Maria-Barbara US-Fondsanbieter. Die Richter/-innen. Jede(r) 1234 \"#+?\""
puts hide_non_capitalized(hide_none)
#=> Änderung. „Uschi“, Attaché-case Maria-Barbara US-Fondsanbieter. Die Richter/-innen. Jede(r) 1234 "#+?"


hide_all = "öfters. „word“ lowercase-Uppercase jede(r) not/exactly/a/word"
puts hide_non_capitalized(hide_all)
#=> ------. „----“ ------------------- ----(-) ---/-------/-/----

【讨论】:

    【解决方案2】:
    ▶ input.gsub(/\p{L}+/) { |m| m[0] != m[0].upcase ? '-'*m.length : m }
    #⇒ "Florian Homm ----- --- Sohn --- ------------------ Handwerksunternehmers..."
    

    更干净的解决方案(感谢 Cary):

    ▶ input.gsub(/(?<!\p{L})\p{Lower}+(?!\p{L})/) { |m| '-' * m.length }
    

    【讨论】:

    • 这个问题比看起来更难。 "Upcase-downcase" 应该转换成什么?
    • 考虑到m是一串字母,m[0] != m[0].upcasem[0] == m[0].downcase不一样吗?也许m[0] =~ /\p{Lower}/ 代替。
    • 来自de.wikipedia.org/wiki/Geschlechtergerechte_Sprache"die Richter/-innen""Jede(r) Anwältin und Anwalt"。德语可能是一种奇怪的语言!
    • @CarySwoveland 很好,我已经用你的想法版本更新了答案。
    【解决方案3】:
    r = /
        (?<![[:alpha:]]) # do not match a letter (negative lookbehind)      
        [[:lower:]]      # match a lowercase letter
        [[:alpha:]]*     # match zero or more letters
        /x               # free-spacing regex definition mode
    
    str = "Frau Maria-Barbara „Uschi“ Homm im hessischen Bad Homburg vor der Höhe auf."
    
    str.gsub(r) { |m| '-'*m.size }
      #=> "Frau Maria-Barbara „Uschi“ Homm -- ---------- Bad Homburg --- --- Höhe ---."
    "die Richter/-innen".gsub(r) { |m| '-'*m.size }
      #=> "--- Richter/------" 
    "Jede(r) Anwältin und Anwalt".gsub(r) { |m| '-'*m.size }
      #=> "Jede(-) Anwältin --- Anwalt" 
    

    【讨论】:

    • 您有语法错误。有了) 更多,它看起来等同于@mudasobwa 的答案。德语是一门复杂的语言,我没有找到任何 100% 正确答案的问题。这里有一桌怪事:de.wikipedia.org/wiki/Geschlechtergerechte_Sprache"die Richter/-innen"经常看到。
    • @Eric,感谢您发现这一点。它似乎适用于您在评论中给出的示例以及对 Mudsie 答案的评论中的另一个示例。没有?
    • "Richter/-innen" 只是一个词。我认为不应该将其中的一部分转换为破折号。
    • 类似地,“Jede(r)”只是一个词。这是一篇文章,意思是“Jede”或“Jeder”,具体取决于后面的内容。
    • @Eric,我放弃了。
    【解决方案4】:

    对于较小的输入大小,您可以尝试这样的操作:

    基本上,我:

    1. 在空格字符上分割输入字符串
    2. 将数组映射到单词本身(如果不大写)或用破折号替换的单词(如果大写)
    3. 加入空格。

    像这样

    s = "Florian Homm wuchs als Sohn des mittelständischen Handwerksunternehmers Joachim Homm und seiner Frau Maria-Barbara „Uschi“ Homm im hessischen Bad Homburg vor der Höhe auf. Sein Großonkel mütterlicherseits war der Unternehmer Josef Neckermann. Nach einem Studium an der Harvard University, das er mit einem Master of Business Administration an der Harvard Business School abschloss, begann Homm seine Tätigkeit in der US-amerikanischen Finanzwirtschaft bei der Investmentbank Merrill Lynch, danach war er bei dem US-Fondsanbieter Fidelity Investments, der Schweizer Privatbank Julius Bär und dem US-Vermögensverwalter Tweedy Browne...."
    
    s.split(/[[:space:]]/).map { |word| word.capitalize == word ? word : '-' * word.length }.join(' ')
    

    这适用于您的问题吗?

    干杯!

    编辑:对于内存效率更高的解决方案,您可以使用正则表达式替换 gsub,查看 mudasobwa https://stackoverflow.com/a/41570686/4411941 的其他答案

    【讨论】:

    • 这既不适用于“Maria-Barbara”,也不适用于“„Uschi“”。有趣的事实:"„Uschi“".capitalize 在 Ruby 2.3 上是 "„uschi“"。不知道为什么!
    • Arf,我想您可以将word.capitalize == word 更改为更符合德国大写单词定义的定义。
    • @EricDuminil capitalize 尝试将第一个字符大写,无论它是否按字母顺序排列,即,而不是U
    • 我忘记了capitalize 也将其余部分缩小了。
    【解决方案5】:

    试试这样的

    s.split.map { |word| ('A'..'Z').include?(word[0]) ? word : '-' * word.length }.join(' ')
    

    【讨论】:

    猜你喜欢
    • 2012-10-23
    • 2018-05-27
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多