首先,有人问before。但是,我无法对其进行修改以满足我的要求。
简而言之:我希望有一个正则表达式与表达式匹配,当且仅当它仅包含数字,并且表达式中某处有5个(或更多)递增连续数字时。
我了解……的逻辑
^(?=\d{5}$)1*2*3*4*5*6*7*8*9*0*$
但是,这会将表达式限制为5位数字。我希望表达式前后都可以有数字。因此1111345671111
应该匹配,而11111
不应该匹配。
我认为这可能有效:
^[0-9]*(?=\d{5}0*1*2*3*4*5*6*7*8*9*)[0-9]*$
我解释为:
^$
:整个表达式只能包含这两个符号之间的内容
[0-9]*
:0
-9
之间的任何数字,0或更多次,后跟:
(?=\d{5}0*1*2*3*4*5*6*7*8*9*)
:找到至少5个递增数字的部分,后跟:
[0-9]*
:0
-9
之间的任何数字,0次或多次。
但是此正则表达式不正确,例如11111
匹配。如何使用正则表达式解决此问题?因此要匹配的表达式示例:
00001459000
12345
这不应该匹配:
abc12345
9871234444
答案 0 :(得分:23)
尽管可以使用纯正则表达式解决此问题(严格递增的五位数字字符串是有限的,所以您可以枚举所有字符串),但它不适用于正则表达式。
也就是说,如果必须的话,这就是我要做的事情:
^\d*(?=\d{5}(\d*)$)0?1?2?3?4?5?6?7?8?9?\1$
核心思想:0?1?2?3?4?5?6?7?8?9?
匹配一个递增的数字子字符串,但不限制其长度。每个部分都是可选的,因此它可以匹配从""
(空字符串)到完整的"0123456789"
的所有内容。
我们可以通过将五位数字的预读与任意后缀(我们捕获到的)和后向引用\1
(必须与前瞻匹配的后缀精确组合)相结合来强制它精确匹配5个字符,确保我们现在已经向前移动了字符串中的5个字符)。
实时演示:https://regex101.com/r/03rJET/3
(顺便说一句,您对(?=\d{5}0*1*2*3*4*5*6*7*8*9*)
的解释是不正确的:它期待完全匹配5个数字,后跟0个或多个出现的0
,然后是0个或多个出现的{{ 1}}等)
答案 1 :(得分:3)
因为预先不知道递增数字的开始位置,并且连续的递增数字不会在字符串的结尾处结束,所以链接的答案的简洁模式在这里不起作用。我认为没有重复就不可能做到这一点。在所有增加数字的可能性之间交替。 0
之后必须是[1-9]
。 (0(?=[1-9])
)1
之后必须是[2-9]
。 2
之后必须是[3-9]
,依此类推。在一组中的这些可能性之间交替,并重复该组四次,然后匹配任意一位数字(前一组中最后一位重复数字的前瞻将确保这第5位数字也是按顺序排列的。
首先 lookahead 表示数字,然后是字符串的结尾,然后匹配上述替代项,然后匹配一个或多个数字:
^(?=\d+$)\d*?(?:0(?=[1-9])|1(?=[2-9])|2(?=[3-9])|3(?=[4-9])|4(?=[5-9])|5(?=[6-9])|6(?=[7-9])|7(?=[89])|8(?=9)){4}\d+
分开以提高可读性:
^(?=\d+$)\d*?
(?:
0(?=[1-9])|
1(?=[2-9])|
2(?=[3-9])|
3(?=[4-9])|
4(?=[5-9])|
5(?=[6-9])|
6(?=[7-9])|
7(?=[89])|
8(?=9)
){4}
\d+
\d*?
的第一行中的惰性量词不是不必要的,但是它使模式更有效(否则,它最初会贪婪地匹配整个字符串,因此需要大量失败的替换和回溯,直到字符串末尾至少5个字符为止)
https://regex101.com/r/03rJET/2
这很丑,但是行得通。