2

给定名称“ Rigobert Song”我如何返回“ Rigobert S.”?

该名称可以是Rigobert J. Song或只是Rigobert。我想为前者Rigobert S.Rigobert后者返回。

我写了这个,它有效。有没有更多的“红宝石方式”?

def initials_for(user)
  if user.name.split.size > 1
    "#{user.name.split.first} #{user.name.split.last[0]}"
  else
    user.name
  end
end
4

5 回答 5

4
"Rigobert J. Song"
.gsub(/\s+.+\s+/, " ").sub(/(?<=\s\S).+/, ".")
# => "Rigobert S."

"Rigobert Song"
.gsub(/\s+.+\s+/, " ").sub(/(?<=\s\S).+/, ".")
 # => "Rigobert S."

"Rigobert"
.gsub(/\s+.+\s+/, " ").sub(/(?<=\s\S).+/, ".")
 # => "Rigobert"
于 2013-08-21T15:07:00.063 回答
2

您不必多次拆分。你可以把它变成一个变量

def initials_for(user)
  name_arry = user.name.split
  name_arry.size > 1 ? "#{name_arry.first} #{name_arry.last[0]}" : user.name
end
于 2013-08-21T15:10:27.057 回答
1

由于您将其标记为 ruby​​-on-rails,我假设您有present?可用的...

def initials_for(full_name)
  (first_name, *, last_name) = full_name.split
  [first_name, name_initial(last_name)].reject(&:blank?).join(" ")
end

def name_initial(name)
  if name.present?
    "#{name[0]}."
  else
    ""
  end
end

puts initials_for(user.name)

首先,我在此帮助程序中考虑了 user 的使用,这是此函数不需要知道的依赖项。按照 puts 行中的指示传递字符串。

正如其他几个人所指出的那样,我做了一个助手来处理带有句点的第二个首字母。然后将这些部分收集到一个数组中,拒绝空白部分,并用空格将它们连接起来。

请注意在拆分的左侧使用了 splat 和意图揭示变量。如果你尝试一下,你应该会看到 first_name 总是有最左边的名字,而 last_name 总是有最右边的名字,如果只有一个名字,则为 nil。

在处理名字、姓氏、中间名、娘家姓和普通名字的变体时,我经常使用这种拒绝和加入的模式,留下一个没有额外字符等的可读名字。

于 2013-08-21T15:34:56.067 回答
1

这也行。但我不知道它是否一定是一个“更好”的解决方案。

def initials_for(user)
  parts = user.name.split
  name = parts.first
  name += " #{parts.last[0]}." if parts.length > 1
  name
end
于 2013-08-21T15:11:06.060 回答
-1

编辑以正确处理提问者的示例字符串

我喜欢使用正则表达式。这允许名字和/或姓氏中的任何字符。字符串中最多只能有两个空格。

如果有零个空格,则所有字符都作为名字放在捕获组 1 中。

如果有一个空格,则空格之前的字符作为名字放在捕获组 1 中,空格之后的字符作为姓氏放在捕获组 3 中。

如果有两个空格,则将第一个空格之前的字符放在捕获组 1 中;捕获组 2 中空格之间的字符;以及捕获组 3 中第二个空格之后的字符。

#output
Testing Rigobert Song
Rigobert S.
Testing Rigobert J. Song
Rigobert S.
Testing Rigobert J.Song
Rigobert J.
Testing RigobertJ.Song
RigobertJ.Song
Testing Rigobert
Rigobert


tests = [ "Rigobert Song", "Rigobert J. Song", "Rigobert J.Song", "RigobertJ.Song", "Rigobert", ]
regex=\
 /^([^ ]*) ?([^ ]* )?([^ ]+)?$/
#- - - - - - - - - - - - - - -
# ^- - - - - - - - - - - - - - Match start of string here
#  ^ - - ^ - - - - - - - - - - Begin/End capture group 1
#   ^^^^^- - - - - - - - - - - Match 0 or more of any non-space character
#         ^^ - - - - - - - - - Match zero or one literal space
#           ^- - - ^ - - - - - Begin/End capture group 2
#            ^^^^^ - - - - - - Match 0 or more non-space characters...
#                 ^- - - - - - ... with exactly one trailing space
#                   ^- - - - Make Capture group 2 optional (match 0 or 1)
#                    ^ - - ^ - Begin/end capture group 3
#                     ^^^^^- - Match 1 or more non-space characters
#                           ^- Make capture group 3 optional
#                            ^ Match end of string here

tests.each do |str|
  puts "Testing #{str}"
  match = regex.match(str)
  if(match != nil)
    first = match[1]
    middle = match[2] || ""
    last = match[3] || ""
    if(first != "" && last != "")
      puts(first+" "+last[0].chr+".") # ruby 1.8
      #puts(first+' '+last[0]+".")     # ruby 1.9
    else
      if(first != "" && last == "")
        puts(first)
      else
        puts('Invalid name format')
      end
    end
  else 
    puts('No regex match')
  end
end
于 2013-08-21T15:52:06.633 回答