简答
是的,可以做到,但你不应该不那样做!
剧透警告:你最好使用strtol,我会在long答案中告诉你原因。
长答案
它可以使用一个奇怪的正则表达式来完成(最糟糕的是一个正则表达式,其中包含 MIN 和 MAX 之间的所有整数列表),但是你 不想要做这样的事。
这是因为这样的任务意味着对正则表达式进行大量处理,而该测试可以用您喜欢的语言在很少的处理中完成(将以下视为伪代码):
if (str_to_int(s) > CMIN && str_to_int(s) < CMAX)
好吧,实际上你可能会告诉我“但如果它是一个 int,它会溢出!”。但是有一些技术可以检测到:
他们都没有使用正则表达式!
但不管怎样,您不必费心费力,因为 C 标准库中已经有一个函数可以为您完成这项工作:strtol 函数!引用手册:
strtol() 函数返回转换结果,除非值会下溢或溢出。如果发生下溢,strtol() 返回 LONG_MIN。如果发生溢出,strtol() 返回 LONG_MAX。在这两种情况下,errno 都设置为 ERANGE。 strtoll() 完全相同(使用 LLONG_MIN 和 LLONG_MAX 而不是 LONG_MIN 和 LONG_MAX)。
为什么会如此庞大?这是因为正则表达式是查看字符流的自动机。当有比赛时,你沿着自动机移动。基本上,您需要:
- 匹配任何 10 个字符的字符串,或者仅当它以
- 开头时才匹配 11 个字符
- 只包含数字,
- 如果以
2开头,后面只能跟0或1,
- 如果以
2开头,后跟1,后面只能跟0、1、2、3或4
- 如果它以
2开头,然后是1,然后是4,则后面只能是1、2、3、4……@987654356 @
- …
- 如果它以
2 开头,后跟... 并以7 结尾,但如果它以- 开头,然后是2,则需要以6 结尾(所以基本上你必须将所有以前的条件复制到另一个以它结尾的子图中)
- 对于任何其他角色,它都是匹配的。
看起来有点像以下:
^(
(
\d|\d\d|\d\d\d|\d\d\d\d|\d\d\d\d\d|\d\d\d\d\d\d|
\d\d\d\d\d\d\d|\d\d\d\d\d\d\d\d|\d\d\d\d\d\d\d\d\d|
[0-2][0-1][0-4][0-7][0-4][0-8][0-3][0-6][0-4][0-8]
)|
-(
\d|\d\d|\d\d\d|\d\d\d\d|\d\d\d\d\d|\d\d\d\d\d\d|
\d\d\d\d\d\d\d|\d\d\d\d\d\d\d\d|\d\d\d\d\d\d\d\d\d|
[0-2][0-1][0-4][0-7][0-4][0-8][0-3][0-6][0-4][0-7]
)
)$
由以下自动机直观地表示(单击图像玩它):
我不确定这有多正确,因为我可能错过了边缘情况,但我希望我能清楚地说明它与用你最喜欢的语言做的比较。如果你真的解析这么一个巨大的自动机,它会:
- 消耗 CPU 时间,
- 烧电,
- 燃烧(燃料|煤|天然气|铀),
- 污染地球,
- 杀死小海豹
所有这些,而不是做一些可以在一个操作中完成的事情,其复杂性是使用正则表达式做同样事情的 1/100。
因此,如果您不想因为糟糕的编程而杀死小海豹,请不要将正则表达式用于未设计用于的东西。
资源
为了更好地理解什么是自动机,正则表达式的工作原理,什么时候使用是个好主意,什么时候是小海豹杀死一只海豹,我只能建议你看看以下课程:
这是@Andie2302 答案的可视化:
-\b(?:
214748364[0-8]|21474836[0-3][0-9]|2147483[0-5][0-9]{2}|
214748[0-2][0-9]{3}|21474[0-7][0-9]{4}|2147[0-3][0-9]{5}|
214[0-6][0-9]{6}|21[0-3][0-9]{7}|20[0-9]{8}|1[0-9]{9}|
[1-9][0-9]{1,8}|[0-9]|-0
)\b|
\b(?:
214748364[0-7]|21474836[0-3][0-9]|2147483[0-5][0-9]{2}|
214748[0-2][0-9]{3}|21474[0-7][0-9]{4}|2147[0-3][0-9]{5}|
214[0-6][0-9]{6}|21[0-3][0-9]{7}|20[0-9]{8}|1[0-9]{9}|
[1-9][0-9]{1,8}|[0-9]|-0
)\b
通过它的匹配自动机:
还是不服气?
HTH