我有一个由Etc
Ruby库抓取的用户列表:
Thomas_J_Perkins
Jennifer_Scanner
Amanda_K_Loso
Aaron_Cole
Mark_L_Lamb
我需要做的是获取完整的名字,跳过中间名(如果给出),并抓住姓氏的第一个字符。输出应如下所示:
Thomas P
Jennifer S
Amanda L
Aaron C
Mark L
我不确定如何做到这一点,我已经尝试抓住所有角色:/\w+/
但是这样可以抓住所有角色。
答案 0 :(得分:6)
我认为没有正则表达式会更简单:
array = "Thomas_J_Perkins".split("_") # split at _
array.first + " " + array.last[0] # .first prints first name .last[0] prints first char of last name
#=> "Thomas P"
答案 1 :(得分:5)
你并不总是需要正则表达式。
有些人在面对问题时会想到,我知道,我会使用 正则表达式。"现在他们有两个问题。 Jamie Zawinski
您可以使用一些简单的Ruby代码
来完成string = "Mark_L_Lamb"
string.split('_').first + ' ' + string.split('_').last[0]
=> "Mark L"
答案 2 :(得分:1)
您可以使用
^([^\W_]+)(?:_[^\W_]+)*_([^\W_])[^\W_]*$
并替换为\1_\2
。请参阅regex demo
[^\W_]
匹配字母或数字。如果您只想匹配字母,请将[^\W_]
替换为\p{L}
。
^(\p{L}+)(?:_\p{L}+)*_(\p{L})\p{L}*$
请参阅updated demo
重点是匹配并捕获第一个字母到第一个_
(带(\p{L}+)
),然后匹配_
+个字母的0 +序列(带{ {1}})然后匹配并捕获最后一个单词的第一个字母(带(?:_\p{L}+)*_
),然后匹配字符串的其余部分((\p{L})
)。
注意:如果您有独立字符串,则将\p{L}*
替换为^
,将\A
替换为$
(如在Ruby \z
中匹配行的开头, ^
匹配行尾。)
$
答案 3 :(得分:1)
我正处于这个阵营中不使用的正则表达式。
str1 = "Alexander_Graham_Bell"
str2 = "Sylvester_Grisby"
"#{str1[0...str1.index('_')]} #{str1[str1.rindex('_')+1]}"
#=> "Alexander B"
"#{str2[0...str2.index('_')]} #{str2[str2.rindex('_')+1]}"
#=> "Sylvester G"
或
first, last = str1.split(/_.+_|_/)
#=> ["Alexander", "Bell"]
first+' '+last[0]
#=> "Alexander B"
first, last = str2.split(/_.+_|_/)
#=> ["Sylvester", "Grisby"]
first+' '+last[0]
#=> "Sylvester G"
但如果你坚持......
r = /
(.+?) # match any characters non-greedily in capture group 1
(?=_) # match an underscore in a positive lookahead
(?:.*) # match any characters greedily in a non-capture group
(?:_) # match an underscore in a non-capture group
(.) # match any character in capture group 2
/x # free-spacing regex definition mode
str1 =~ r
$1+' '+$2
#=> "Alexander B"
str2 =~ r
$1+' '+$2
#=> "Sylvester G"
你当然可以写
r = /(.+?)(?=_)(?:.*)(?:_)(.)/
答案 4 :(得分:0)
答案 5 :(得分:0)
让我们看看这是否有效:
/^([^_]+)(?:_\w)?_(\w)/
然后你必须将第一和第二场比赛组合成你想要的格式。我不认识Ruby,所以我无法帮助你。
答案 6 :(得分:0)
使用替换方法的另一种尝试:
result = subject.gsub(/^([^_]+)(?:_[^_])?_([^_])[^_]+$/, '\1 \2')
我们捕获整个字符串,捕获组中的相关部分。然后只返回两个捕获的组
答案 7 :(得分:0)
使用split方法要好得多
full_names.map do |full_name|
parts = full_name.split('_').values_at(0,-1)
parts.last.slice!(1..-1)
parts.join(' ')
end
答案 8 :(得分:-1)
/ ^ [A-ZA-Z] {5,15} \ S [A-ZA-Z] {1}] $ / I 这将具有以下标准: 首字母为5-15个字符,然后是空格,最后是姓氏的单个字符。