检查Ruby on Rails中的字符串是否包含连续字符

Ari*_*rif 1 ruby ruby-on-rails-4

尝试验证字符串以确定它是否包含3个或更多的连续字符.

例:

"11abcd$4567" => ['abcd', '4567']
Run Code Online (Sandbox Code Playgroud)

尝试通过正则表达式执行此操作,但代码看起来要长得多:

(?!abc|bcd|cde|.....)
Run Code Online (Sandbox Code Playgroud)

是否有一种简单的方法可以通过正则表达式或纯红宝石检查顺序字符?

Ama*_*dan 7

Regexp在这里不合适.他们不够灵活,不能构建一般案例; 并且Unicode是巨大的,并且构建响应任何升序字符序列的正则表达式将列出数十或数十万个案例中的每一个.它可以以编程方式完成,但这需要时间,并且在内存方面会非常昂贵.

def find_streaks(string, min_length=3)
  string                                 # "xabcy"
    .each_char                           # ['x', 'a', 'b', 'c', 'y']
    .chunk_while { |a, b| a.succ == b }  # [['x'], ['a', 'b', 'c'], ['y']]
    .select { |c| c.size >= min_length } # [['a', 'b', 'c']]
    .map(&:join)                         # ['abc']
end
Run Code Online (Sandbox Code Playgroud)

我想这可能会起到填充剂的作用......试一试?

                                         # skip this thing on Ruby 2.3+, unneeded
unless Enumerable.instance_methods.include?(:chunk_while)
  module Enumerable
    def chunk_while                      # let's polyfill!
      streak = nil                       # twofold purpose: init `streak` outside
                                         # the block, and `nil` as flag to spot
                                         # the first element.

      Enumerator.new do |y|              # `chunk_while` returns an `Enumerator`.
        each do |element|                # go through all the elements.
          if streak                      # except on first element:
            if yield streak[-1], element # give the previous element and current
                                         # one to the comparator block.
                                         # `streak` will always have an element. 
              streak << element          # if the two elements are "similar",
                                         # add this one to the streak;
            else                         # otherwise
              y.yield streak             # output the current streak and
              streak = [element]         # start a new one with the current element.
            end
          else                           # for the first element, nothing to compare
            streak = [element]           # so just start the streak.
          end
        end
        y.yield streak if streak         # output the last streak;
                                         # but if `streak` is `nil`, there were
                                         # no elements, so no output.
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

嗯,derp.在这里,我手写这一切......当它可以像这样简单:

unless Enumerable.instance_methods.include?(:chunk_while)
  module Enumerable
    def chunk_while
      slice_when { |a, b| !yield a, b }
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

是的,chunk_while是的正好相反slice_when.甚至可以在原始代码中替换它,如.slice_when { |a, b| a.succ != b }.有时候我很慢.