5

给定字符串:

strs = [
  "foo",
  "    ",
  "Hello \n there",
  " Ooh, leading and trailing space!  ",
]

我想要一个简单的方法,依次识别所有连续运行的空白和非空白字符,以及运行是否为空白:

strs.each{ |str| p find_whitespace_runs(str) }
#=> [ {k:1, s:"foo"} ],
#=> [ {k:0, s:"    "} ],
#=> [ {k:1, s:"Hello"}, {k:0, s:" \n "}, {k:1, s:"World"} ],
#=> [
#=>   {k:0, s:" "},
#=>   {k:1, s:"Ooh,"},
#=>   {k:0, s:" "},
#=>   {k:1, s:"leading"},
#=>   {k:0, s:" "},
#=>   {k:1, s:"and"},
#=>   {k:0, s:" "},
#=>   {k:1, s:"trailing"},
#=>   {k:0, s:" "},
#=>   {k:1, s:"space!"},
#=>   {k:0, s:"  "},
#=> ]

{k:0, s:""}这几乎可以工作,但只要字符串不以空格开头,就会包含一个前导组:

def find_whitespace_runs(str)
  str.split(/(\S+)/).map.with_index do |s,i|
    {k:i%2, s:s}
  end
end

现实世界的动机:编写一个语法高亮器,在其他未分类的代码中区分空格和非空格。

4

2 回答 2

5
def find_whitespace_runs(str)
  str.scan(/((\s+)|(\S+))/).map { |full, ws, nws|
    { :k => nws ? 1 : 0, :s => full } 
  }
end
于 2013-06-05T03:52:28.503 回答
0

这行得通,但我不喜欢unless empty?(and compact) 的存在。

def find_whitespace_runs(str)
  str.split(/(\S+)/).map.with_index do |s,i|
    {k:i%2, s:s} unless s.empty?
  end.compact
end

我很乐意为任何产生正确结果的答案投票,并会接受任何更优雅或明显更有效的答案。

于 2013-06-05T03:11:30.657 回答