我正在寻找一个匹配从 1 到 50(包括 1 到 50)的任何数字的正则表达式。到目前为止,我已经找到了一些示例,但它们都允许字符串包含小数点,我不想包含小数点。所以 1,13,24,50 可以,但 1. 等不是。有我可以使用的 REGEXP 吗?
在此先感谢,蒂姆
试试这个:
/^(?:[1-9]|[1-4][0-9]|50)$/
现在我看到问题已更新为引用 MySQL,这显着改变了事情。上述正则表达式使用 MySQL 不支持的非捕获括号。但这也引出了一个问题;你真的应该使用正则表达式来解决这个问题吗?我们真的必须看看你如何存储你的数字,必须在 1 到 50 之间。它们varchar
是 s 吗?他们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)
此查询将执行良好,因为它可以使用索引,而且它也更易读和更易于维护。全场取胜。
'^(0?\d|[1-4]\d|50)$'
那是:
编辑:上面允许你肯定不想要的 0(和 00)。所以,假设你真的不希望允许前导零:
'^([1-9]|[1-4]\d|50)$'
编辑:由于 OP 的后续评论表明这是针对 MySQL 的,因此我更改了指定模式的语法。
^([1-9]|[1-4][0-9]|50)$
Perl6::Rules的“作弊” :
/ ( \d+ ) { 1 <= $1 && $1 <= 50 or fail } /
或者在 Perl 5.10 及更高版本中,
/(\d+)(?(?{1>$1||50<$1})(*FAIL))/
试试这个
([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