Регулярное выражение для 1-50 без десятичной точки - PullRequest
4 голосов
/ 03 декабря 2010

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

Заранее спасибо, Тим

Ответы [ 5 ]

8 голосов
/ 03 декабря 2010

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

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

UPDATE:

Теперь, когда я вижу, что вопрос был обновлен для ссылки на MySQL, это значительно меняет ситуацию. Вышеупомянутое регулярное выражение использует парентные символы без захвата, которые не поддерживаются 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)

Это работает, но оно плохо работает с большими наборами данных, поскольку не может использовать индекс, даже если он присутствует. 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)

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

4 голосов
/ 03 декабря 2010
'^(0?\d|[1-4]\d|50)$'

То есть:

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

Редактировать: Выше разрешено 0 (и 00), что вы, конечно, не хотите.Итак, если вы действительно не хотите, чтобы начальные нули были разрешены, так или иначе:

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

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

1 голос
/ 03 декабря 2010

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

0 голосов
/ 03 декабря 2010

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

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

сделает следующее

45.00 - Match
4     - Match
78    - Not Match
51    - Not Match
21.25 - Match
0 голосов
/ 03 декабря 2010

"Обман" с Perl6 :: Правила :

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

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

/(\d+)(?(?{1>$1||50<$1})(*FAIL))/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...