名称为“Rigobert Song
”如何返回“Rigobert S.
”?
名称可以是Rigobert J. Song
,也可以是Rigobert
。我想为之前的Rigobert S.
和后者的Rigobert
返回。
我写了这个,有效。是否有更多“Ruby方式”?
def initials_for(user)
if user.name.split.size > 1
"#{user.name.split.first} #{user.name.split.last[0]}"
else
user.name
end
end
答案 0 :(得分: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"
答案 1 :(得分:2)
您不必多次拆分。你可以把它变成一个变量
def initials_for(user)
name_arry = user.name.split
name_arry.size > 1 ? "#{name_arry.first} #{name_arry.last[0]}" : user.name
end
答案 2 :(得分:1)
这也会奏效。但我不知道它是否一定是一个“更好”的解决方案。
def initials_for(user)
parts = user.name.split
name = parts.first
name += " #{parts.last[0]}." if parts.length > 1
name
end
答案 3 :(得分: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)
首先,我在这个帮助器中考虑了用户的使用,这是这个函数不需要知道的依赖。按照放置行中的指示传入字符串。
我做了一个帮助来处理第二个初始化,其中有一个句号,其他几个表示..然后将这些部分收集到一个数组中,拒绝空白部分,并用空格连接它们。
请注意在分割的左侧使用splat和intent揭示变量。如果您尝试它,您应该看到first_name始终具有最左侧的名称,last_name始终具有最右侧的名称,如果只存在一个名称,则为nil。
在处理第一个,最后一个,中间名,首个和常用名的变体时,我使用这种拒绝和加入的模式,留下一个没有额外字符等的可读名称。
答案 4 :(得分:-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