Как проверить серию уникальных чисел?

#ruby-on-rails #regex #validation

#ruby-on-rails #регулярное выражение #проверка

Вопрос:

 validates_format_of            :order_of_importance, :on => :create, :with => /^[1-3]{3}$/,
                             :message => "Order of Importance must have 3 Digits"
  

Прямо сейчас я проверяю, что используемые числа являются либо 1, 2, 3 , но я также хочу убедиться, что эти числа не только используются, но и что каждое из них используется только один раз.

Например:

Должны быть рабочие числа

2 3 1

1 3 2

1 2 3

Не должно быть рабочих чисел:

1 1 2

2 2 1

3 3 3

Комментарии:

1. Есть ли конкретная причина, по которой вы хотите использовать регулярное выражение? Я бы использовал метод.

2. Без конкретной причины. Это именно то, с чего я начал. Я думаю, это доходит до того, что метод становится более важным. В таком случае, как бы вы составили метод?

3. Честно говоря, я бы, наверное, просто сделал uniq! и посмотрите, совпадает ли он с размером оригинала. Иногда я немного ленив. (Предполагая, что они находятся в массиве.) Можно также выгрузить их на карту и сравнить размеры массива / карты.

4. согласен с Дэйвом, эту задачу можно легко решить с помощью sth like str.split('').uniq.length == 3 , и трудно найти подходящее регулярное выражение

Ответ №1:

 if subject =~ /A(?:A(?=[1-3]{3}Z)(d)(?!1)(d)(?!(?:1|2))dZ)Z/
    # Successful match
else
    # Match attempt failed
end
  

Это будет соответствовать строке с ровно 3 числами в диапазоне 1-3 без повторяющихся чисел.

Разбивка :

 "
^              # Assert position at the beginning of the string
(?=            # Assert that the regex below can be matched, starting at this position (positive lookahead)
   [1-3]          # Match a single character in the range between “1” and “3”
      {3}            # Exactly 3 times
   $              # Assert position at the end of the string (or before the line break at the end of the string, if any)
)
(              # Match the regular expression below and capture its match into backreference number 1
   \d             # Match a single digit 0..9
)
(?!            # Assert that it is impossible to match the regex below starting at this position (negative lookahead)
   \1             # Match the same text as most recently matched by capturing group number 1
)
(              # Match the regular expression below and capture its match into backreference number 2
   \d             # Match a single digit 0..9
)
(?!            # Assert that it is impossible to match the regex below starting at this position (negative lookahead)
   (?:            # Match the regular expression below
                     # Match either the regular expression below (attempting the next alternative only if this one fails)
         \1             # Match the same text as most recently matched by capturing group number 1
      |              # Or match regular expression number 2 below (the entire group fails if this one fails to match)
         \2             # Match the same text as most recently matched by capturing group number 2
   )
)
\d             # Match a single digit 0..9
$              # Assert position at the end of the string (or before the line break at the end of the string, if any)
"
  

Ответ №2:

Не проще ли проверить все 3! допустимые перестановки?

Редактировать:

Но принять вызов: (?:1(?!d*1)|2(?!d*2)|3(?!d*3)){3}

Он использует отрицательные ожидания, чтобы убедиться, что числа выбираются только один раз.

Редактировать:

Проверено с помощью rubular.com .

Ответ №3:

вы можете разбить строку на 3 числа. a, b и c.

тогда у вас есть много способов проверить. например

минимальное значение == 1, максимальное == 3 и сумма = 6

поместите 3 в набор (я надеюсь, что ruby имеет тип коллекции set), размер набора должен быть 3.

и т.д..

регулярное выражение может быть не лучшим инструментом для решения этой проблемы.

Ответ №4:

Как уже говорили другие, лучше проверять уникальность с помощью метода или чего-то еще. Но если у вас есть причина использовать регулярное выражение, тогда регулярное выражение будет выглядеть примерно так

 ^(d)s*(?!1)(d)s*(?!1|2)(d)$
  

Он использует отрицательный предварительный просмотр для каждой из цифр для проверки повторения путем проверки aginst уже захваченных групп. Если вам нужно проверять только 1,2 и 3, вы можете использовать это

 ^([123])s*(?!1)([123])s*(?!1|2)([123])$
  

Ответ №5:

Я бы настоятельно рекомендовал [Онлайн-конструктор регулярных выражений] [1]

[1]: http://www.gskinner.com/RegExr / чтобы избежать сомнений

Комментарии:

1. упс, извиняюсь, Дэйв, но, возможно, в некотором роде полезно для QO

2. Согласен, но более уместно в качестве комментария.