【问题标题】:How do I remove certain words from a string, but only if they appear at the end of the string?如何从字符串中删除某些单词,但前提是它们出现在字符串的末尾?
【发布时间】:2013-11-08 13:01:58
【问题描述】:

我的公司名称有“The Millard Group”和“The Chimney Corporation”。我想删除“集团”或“公司”之类的词,但前提是它们出现在词的最后。 IE。如果它们出现在中间的某个地方,我不想删除它们。

我怎样才能在 Ruby 中做到这一点? gsub 将从任何位置替换字符串,而且我有一个大约十个列表,所以我宁愿不运行 gsub 十次。如果我能提供这些单词的数组来删除,那就太好了。

【问题讨论】:

  • 你的意思是单词或行或字符串的结尾吗?

标签: ruby regex


【解决方案1】:

试试这样的:

['The Millard Group', 'The Chimney Corporation'].each do |s|
  s.gsub!(/\ (Group|Corporation)$/, '')
end

您可以在正则表达式中添加更多要删除的单词,方法是在更多|之后添加它们

【讨论】:

  • 小心$,它的真正意思是“行尾”,\z\Z 表示“字符串结尾”(对最终换行符的处理不同)。
  • @Ringo,如果这是对您问题的最佳有效答案,请您给它(或任何最好的问题)打勾?这将向发现您的问题的其他人显示哪个答案对您有帮助。
【解决方案2】:

因为不是所有的事情都需要用 gsub 和 regexp 来解决:

endings = [' Group', ' Corporation']
corporations = ["The Millard Group", "The Chimney Corporation"]

corporations.each do |corp|
  endings.each{|ending| corp.chomp!(ending)}
end

p corporations #=> ["The Millard", "The Chimney"]

编辑:也许这个版本会快一点?

corporations.map! do |corp|
  last_word = (corp.rindex(' ')+1)..-1
  corp.slice!(last_word) if endings.include?(corp[last_word])
  corp.rstrip
end

【讨论】:

  • 虽然这更简单且更易于阅读,但随着列表的增长,使用包含搜索词并集的正则表达式模式会更快,尤其是在锚定时。
  • 非常好,@hirolau,确实非常好。我似乎总是将chompgets.chomp 联系在一起,忘记了它可以引起争论。一个很好的提醒。也许在corp 之后插入rstrip!
【解决方案3】:

使用以下约定:

\s 表示空格/换行符等。
$ 表示在行尾。 ^ 表示在行首。

现在在你的正则表达式中使用它:

/\s*(Group|Corporation)$/

这将在您给定的String 的末尾找到 GroupCorporation,并将其替换为您想要的任何内容。

'The Chimney Corporation'.gsub!(/\s*(Group|Corporation)$/,'')
#=>"The Chimney"

【讨论】:

  • 使用\s+ 而不是\s*。第一个强制剥离 1+ 个空格字符,这将允许 gsub 仅在单词独立时触发。使用 \s* 将允许 0+,即使“公司”或“集团”附加到可能导致误报的前一个单词。
【解决方案4】:
arr = [ "The Millard Group", "The Chimney Corporation", "The Ruby People" ]
BAD_WORDS = %w{ Group Corporation }

arr.reduce([]) do |a,s| 
  s.match( /(.*?)\s+(\w+)\s*$/ )
  a << ( BAD_WORDS.include?($2) ? $1 : s )
end
    # => ["The Millard", "The Chimney", "The Ruby People"] 
  • arr.reduce([]) 在块内创建一个名为a 的空数组,其中将插入可能修改的字符串。

  • s.match(/(.*?)\s+(\w+)\s*$/) 有两个捕获组;第二个用于字符串的最后一个单词(\w+),其前面至少有一个空格字符\s+,第一个用于该空格之前的所有内容,(.*?)? 需要制作它“不贪婪”。匹配结果存储在$1$2中。

  • 我们检查$2(字符串s的最后一个字)是否包含在BAD_WORDS中;如果是,我们将$1 附加到a,否则我们附加 整个字符串s

[编辑:我更喜欢迄今为止发布的其他解决方案,但出于多样性考虑,我将保留此解决方案。]

【讨论】:

    猜你喜欢
    • 2021-05-23
    • 2022-01-24
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多