我正在制作地址列表,例如:
New york city23 b
Miami 355c
我需要它们看起来像
New York City 23 B
Miami 355 C
问题是在字母+数字组合之前和之后添加空格。我想出了以下正则表达式来突出问题:
/\p{L}\d|\d\p{L}/
但我错过了在这些之间实际设置空间的逻辑。现在代码看起来像
"moscow city46 d".titleize.gsub(/\p{L}\d|\d\p{L}/, ' \0')
# titleize is a Rails method
输出
Moscow Cit y46 D
答案 0 :(得分:5)
由于您使用了titleize
我假设您不介意使用其他ActiveSupport方法。它不像某些人那样“聪明”,但String#squish
用一个空格替换连续空格的运行,这是一个非常简单的解决方案:
str.gsub(/\d+/, ' \0 ').squish.titleize
Ruby(sans Rails)有一个类似的String#squeeze
方法,但与squish
不同,它不会修剪前导和尾随空格,因此必须与String#strip
结合使用。
答案 1 :(得分:4)
使用lookarounds并替换为单个空格:
.gsub(/(?<=\p{L})(?=\d)|(?<=\d)(?=\p{L})/, ' ')
(?<=\p{L})(?=\d)|(?<=\d)(?=\p{L})
正则表达式将匹配2个位置:
(?<=\p{L})(?=\d)
- 字母和数字之间的位置|
- 或(?<=\d)(?=\p{L})
- 数字和字母之间的位置。因此,空间将被插入&#34;在数字或字母之间。
答案 2 :(得分:2)
'New york city23 b'.scan(/\D+|\d+/).flat_map(&:split).map(&:capitalize).join(' ')
# => "New York City 23 B"
答案 3 :(得分:1)
这是一个非正则表达式纯Ruby解决方案。
cities =<<-_
New york city23 b
Miami 355c
_
cities.each_char.each_cons(2).map do |a,b|
str = a+b
r = /[[:alpha:]][[:digit:]]/
str =~ r || str.reverse =~ r ? "#{a} " : a
end.join.split.map(&:capitalize).join(' ')
#=> "New York City 23 B Miami 355 C"