Учитывая сложность тестирования длинных регулярных выражений, а также возможность - если не вероятность - что изменения понадобятся в будущем, я бы склонен разбить строку на дефисы и протестировать каждую строку в результирующем массиве.
PIECES = [['qwer'],
['0123a4bcd567890e1'.size],
['uuuuu3xx'.size, '.qwer'],
['gfd'],
['1e098765dcb4a3210'.size, '.ps'],
['sdlk'],
[[1, 2], '.qwer.domain.com']].
map do |a|
Regexp.new(
a.each_with_object('\A') do |o,s|
case o
when String
s << o.gsub('.', '\.')
when Integer
s << "\\p{Alnum}{#{o}}"
else # array
s << "\\p{Alnum}{#{o.first},#{o.last}}"
end
end << '\z')
end
#=> [/\Aqwer\z/, /\A\p{Alnum}{17}\z/, /\A\p{Alnum}{8}\.qwer\z/,
# /\Agfd\z/, /\A\p{Alnum}{17}\.ps\z/, /\Asdlk\z/,
# /\A\p{Alnum}{1,2}\.qwer\.domain\.com\z/]
Обратите внимание, что я использовал одинарные кавычки в большинстве мест, чтобы иметь возможность писать, например, '\A'
вместо "\\A"
.Однако двойные кавычки необходимы для двух строк, где выполняется интерполяция (#{o}
).Я также использовал строки из этого примера, чтобы определить длины различных серий буквенно-цифровых символов, а также избежал точек и добавил якоря в простом коде.Я сделал это, чтобы уменьшить вероятность подсчета ошибок и помочь читателям кода понять, что делается.Хотя элементы PIECES
(регулярные выражения) здесь используются для проверки строки, используемой для построения PIECES
, что, конечно, не имеет значения, если предположить, что все строки, подлежащие проверке, будут иметь одинаковый шаблон.
def valid?(str)
arr = str.split('-')
return false unless arr.size == PIECES.size
arr.zip(PIECES).all? { |s,r| s.match? r }
end
Если Enumerable # all? * Блок 1013 * возвращает false all?
, немедленно возвращается false
.Это иногда называют короткое замыкание поведение.
Для строки, приведенной в примере, str
,
valid?(str)
#=> true
Обратите внимание на следующие промежуточные вычисления.
str.split('-').zip(PIECES)
#=> [["qwer", /\Aqwer\z/],
# ["0123a4bcd567890e1", /\A\p{Alnum}{17}\z/],
# ["uuuuu3xx.qwer", /\A\p{Alnum}{8}\.qwer\z/],
# ["gfd", /\Agfd\z/],
# ["1e098765dcb4a3210.ps", /\A\p{Alnum}{17}\.ps\z/],
# ["sdlk", /\Asdlk\z/],
# ["6.qwer.domain.com", /\A\p{Alnum}{1,2}\.qwer\.domain\.com\z/]]
Это может показаться излишним (и я не уверен, что это не так), но это облегчает отладку и тестирование, и если в будущем шаблон строки изменится (в определенных пределах), это должно бытьОтносительно легко изменить тест на соответствие (путем изменения указанного выше массива массивов, из которого получается PIECES
).