2010-12-03 7 views
4

Я ищу регулярное выражение, которое будет соответствовать любому числу от 1 до 50 включительно. До сих пор я нашел примеры, но все они позволяют содержать строку с десятичной точкой, которую я не хочу включать. Так 1,13,24,50 в порядке, но 1. и т. Д. Нет. Есть ли REGEXP, который я могу использовать?Регулярное выражение для 1-50 без десятичной точки

Спасибо заранее, Tim

ответ

6

Попробуйте это:

/^(?:[1-9]|[1-4][0-9]|50)$/ 

UPDATE:

Теперь, когда я вижу этот вопрос был обновлен, чтобы обратиться к MySQL, это существенно меняет дело. Вышеупомянутое регулярное выражение использует не-захват parens, которые не поддерживаются MySQL. Но это также вызывает вопрос; если вы действительно используете регулярные выражения для решения этой проблемы? Нам действительно нужно посмотреть, как вы храните свои цифры, которые должны быть между 1 и 50. Есть ли они varchar? Являются ли они int? Я продемонстрирую, как решить это в обоих направлениях. Сначала я создал тестовую таблицу с индексами:

create table regextest (
    id int unsigned primary key auto_increment, 
    varchar_number varchar(5) not null, 
    int_number int not null, 
    index(varchar_number), 
    index(int_number) 
) engine=innodb; 

Теперь поставить некоторые тестовые данные в это убедившись, что все наши крайние случаи покрыты:

insert into regextest (varchar_number, int_number) 
    values ('0', 0), ('1', 1), ('35', 35), ('49', 49), ('50', 50), ('51', 51); 

А теперь, вот запрос, решит вашу проблему при условии, что ваши номера хранятся в виде строк в varchar_number колонке:

mysql> select * from regextest where varchar_number rlike '^([1-9]|[1-4][0-9]|50)$'; 
+----+----------------+------------+ 
| id | varchar_number | int_number | 
+----+----------------+------------+ 
| 2 | 1    |   1 | 
| 3 | 35    |   35 | 
| 4 | 49    |   49 | 
| 5 | 50    |   50 | 
+----+----------------+------------+ 
4 rows in set (0.00 sec) 

Это работает, но он будет выполнять плохо на больших наборах данных, поскольку она не может у se индекс, даже если он присутствует. MySQL должен запускать регулярное выражение один раз для каждой строки таблицы. Предположим, что ваши номера от 1 до 50 были сохранены как int s в столбце int_number. Вы могли бы просто сделать это:

mysql> select * from regextest where int_number between 1 and 50; 
+----+----------------+------------+ 
| id | varchar_number | int_number | 
+----+----------------+------------+ 
| 2 | 1    |   1 | 
| 3 | 35    |   35 | 
| 4 | 49    |   49 | 
| 5 | 50    |   50 | 
+----+----------------+------------+ 
4 rows in set (0.00 sec) 

Этот запрос будет хорошо работать, поскольку он может использовать индекс, а также более читабельным и более удобным. Выигрывает со всех сторон.

+0

привет, спасибо за ваш комментарий. Я пытаюсь сделать следующее в MySQL: Выберите 1 REGEXP '/^(?: [1-9] | [1-4] [0-9] | 50) $ /', но при этом возникает ошибка: Got error ' операнд-оператор повторения недействителен "из regexp. Я видел, что это может быть связано с тем, что вы не избегаете обратного слэша, и я попытался сделать // вместо /, но все равно не работал ... Любые идеи? – Tim 2010-12-03 08:50:33

+0

@Tim: Проблема, вероятно, в синтаксисе `(?: ...)`, в котором вводится группа, не захватывающая запись. Похоже, что MySQL этого не поддерживает, и пытается рассматривать `?` Как оператор повторения, хотя, конечно, ему нечего повторять. Если вы замените `(?: ...)` обычными скобками `(...)`, он должен работать. – 2010-12-03 10:53:07

+0

Спасибо, я попробовал, но/^ (([1-9] | [1-4] [0-9] | 50) $ /), но он не соответствует правильным цифрам. – Tim 2010-12-03 11:36:57

4
'^(0?\d|[1-4]\d|50)$' 

То есть:

  • начала ввода
  • , за которым следует одна цифра (необязательно предшествует 0), или
  • с последующим 1-4 с последующим любым или
  • , а затем 50
  • , а затем убедитесь, что мы видим конец ввода.

Edit: выше позволяет 0 (и 00), которые вы наверняка не хотите. Таким образом, предполагая, что вы действительно не хотите, ведущие нули позволили так или иначе:

'^([1-9]|[1-4]\d|50)$' 

Edit: В последующих комментариях Op указывают, что это для MySQL, я изменил синтаксис для задания шаблона.

0

"Обман" с Perl6::Rules:

/ (\d+) { 1 <= $1 && $1 <= 50 or fail }/

Или в Perl 5.10 и выше,

/(\d+)(?(?{1>$1||50<$1})(*FAIL))/ 
0

попробовать это один

([0-4]{1}[0-9]{0,1}[.]{0,1}[0-9]{0,2}|50) 

будет ли Fo llowing

45.00 - Match 
4  - Match 
78 - Not Match 
51 - Not Match 
21.25 - Match