在Ruby中插入字母和数字之间的空格

时间:2017-04-12 14:26:00

标签: ruby regex

我正在制作地址列表,例如:

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

4 个答案:

答案 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"