如何在MySQL中编写匹配3位及以上升/降序连续数字的REGEX?
验证现有正则并优化升/降序数字序列匹配方案
现有正则正确性验证
你当前使用的正则:
\b(123(4(5)?)?|234(5)?|345|456|567(8(9)?)?|678(9)?|789|987(6(5)?)?|876(5)?|765|654|543(2(1)?)?|432(1)?)\b
- 正确覆盖了需求中的示例场景(1234、2345、5432、98765等),能匹配所有长度3-5的连续升序/降序数字序列
- 但存在明显缺陷:写法冗余,枚举式的规则维护性差,若后续需要调整序列长度或扩展匹配范围,修改成本极高
更简洁高效的正则实现
利用MySQL正则支持的正向预查和反向引用特性,通过动态匹配数字间的递增/递减关系实现,无需枚举所有可能序列:
合并后的完整正则(适配Laravel查询)
'sequential' => function ($query) { // 匹配长度≥3的连续升序或降序数字序列 $pattern = '\b(?: (?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){2,}\d | (?:9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){2,}\d )\b'; $query->orWhereRaw('plate_number REGEXP ?', [$pattern]); },
规则解释
- 升序匹配部分:
(?:0(?=1)|1(?=2)|...|8(?=9)){2,}\dx(?=y):正向预查,确保当前数字x的下一个数字是x+1{2,}:要求这种递增关系至少出现2次,保证序列长度≥3- 末尾
\d匹配序列的最后一个数字
- 降序匹配部分:逻辑与升序一致,只是预查规则变为
x的下一个数字是x-1 - 边界处理:
\b确保匹配的是独立的数字序列,避免和车牌中的字母或其他数字片段混淆
扩展适配
如果车牌存在字母与数字混合的场景(如A1234B),\b单词边界可能失效,可替换为数字边界断言:
$pattern = '(?<![0-9])(?: (?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){2,}\d | (?:9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){2,}\d )(?![0-9])';
(?<![0-9])和(?![0-9])分别表示匹配位置的前后都不是数字,精准锁定独立数字序列
内容的提问来源于stack exchange,提问作者Mimi
相关产品推荐
相关产品推荐

