#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}
Он использует отрицательные ожидания, чтобы убедиться, что числа выбираются только один раз.
Редактировать:
Ответ №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. Согласен, но более уместно в качестве комментария.