可以重构此数值范围的正则表达式吗

Can this numeric range regex be refactored?

本文关键字:范围 正则表达式 重构      更新时间:2024-06-30

我需要匹配一个数字范围:

-92233720368547758089223372036864775807

^(?:922337203685477580[0-7]|9223372036854775[0-7]'d{2}|922337203685477[0-4]'d{3}|92233720368547[0-6]'d{4}|9223372036854[0-6]'d{5}|922337203685[0-3]'d{6}|92233720368[0-4]'d{7}|9223372036[0-7]'d{8}|922337203[0-5]'d{9}|92233720[0-2]'d{10}|922337[0-1]'d{12}|92233[0-6]'d{13}|9223[0-2]'d{14}|922[0-2]'d{15}|92[0-1]'d{16}|9[01]'d{17}|[1-8]'d{18}|'d{0,18}|-(?:922337203685477580[0-8]|9223372036854775[0-7]'d{2}|922337203685477[0-4]'d{3}|92233720368547[0-6]'d{4}|9223372036854[0-6]'d{5}|922337203685[0-3]'d{6}|92233720368[0-4]'d{7}|9223372036[0-7]'d{8}|922337203[0-5]'d{9}|92233720[0-2]'d{10}|922337[0-1]'d{12}|92233[0-6]'d{13}|9223[0-2]'d{14}|922[0-2]'d{15}|92[0-1]'d{16}|9[01]'d{17}|[1-8]'d{18}|'d{0,18}))?$
// space for easier copy and paste

是的,我知道这听起来很疯狂,但这背后有很长的故事。由于数字的大小,我无法在JavaScript中通过检查范围来实现这一点,这必须是准确的。

以下是分解这件事的思维过程。我刚从最大值开始,一路向下,然后通过在正则表达式中添加-来处理负数。很明显,你必须把这个东西复制粘贴到某个地方才能看到它。也可能是错误。让我的头差点爆炸。

  • 9223372036854775807
  • 922337203685477580[0-7]
  • 9223372036854775[0-7][0-9]{2}
  • 922337203685477[0-4][0-9]{3}
  • 92233720368547[0-6][0-9]{4}
  • 9223372036854[0-6][0-9]{5}
  • 922337203685[0-3][0-9]{6}
  • 92233720368[0-4][0-9]{7}
  • 9223372036[0-7][0-9]{8}
  • 922337203[0-5][0-9]{9}
  • 92233720[0-2][0-9]{10}
  • 922337[0-1][0-9]{12}
  • 92233[0-6][0-9]{13}
  • 9223[0-2][0-9]{14}
  • 922[0-2][0-9]{15}
  • 92[0-1][0-9]{16}
  • 9[01][0-9]{17}
  • [1-8][0-9]{18}
  • [0-9]{0,18}

负数和正数有一个位数的不同,所以你会看到我在哪里基本上复制了大部分内容。

所以有几个问题:

  1. 我做对了吗
  2. 如果没有,还有什么更好的方法
  3. 如果没有考虑数字大小的正则表达式,这能做到吗?我需要验证客户端
  4. 它能被重构并仍然保留严格的规则吗

建议感谢:)

如果没有考虑数字大小的正则表达式,这能做到吗?

它可以在一系列仅使用字符串操作的if语句中完成(无需转换为数字)。

  • 所有不匹配[0-9]{1,19}的字符串都已退出

  • 长度为18或以下的所有候选都是良好的

  • 对于长度19,您可以使用字符串比较来查看它们在数字上是否小于的上限

  • 调整以上内容以处理负数

您的正则表达式是正确的。这是一个较短版本的

^(?:-9223372036854775808|-?(?:'d{0,18}|(?!922337203685477580[8-9]|92233720368547758[1-9]|92233720368547759|922337203685477[6-9]|92233720368547[8-9]|9223372036854[8-9]|922337203685[5-9]|92233720368[6-9]|92233720369|922337203[7-9]|92233720[4-9]|9223372[1-9]|922337[3-9]|92233[8-9]|9223[4-9]|922[4-9]|92[3-9]|9[3-9])'d{19}))$

Regex演示

如何毫无错误地生成正则表达式:
输入最大数量:

9223372036854775807

输出

9223372036854775807
922337203685477580
92233720368547758
9223372036854775
922337203685477
92233720368547
9223372036854
922337203685
92233720368
9223372036
922337203
92233720
9223372
922337
92233
9223
922
92
9   

替换最后一个数字字母

9->remove all line
8->9
7->[8-9]
6->[7-9]
5->[6-9]
4->[5-9]
3->[4-9]
2->[3-9]
1->[2-9]
0->[1-9]

输出

922337203685477580[8-9]
92233720368547758[1-9]
92233720368547759
922337203685477[6-9]
92233720368547[8-9]
9223372036854[8-9]
922337203685[5-9]
92233720368[6-9]
92233720369
922337203[7-9]
92233720[4-9]
9223372[1-9]
922337[3-9]
92233[8-9]
9223[4-9]
922[4-9]
92[3-9]
9[3-9]

Regex[输出]
922337203685477580[8-9]|92233720368547758[1-9]|92233720368547759|922337203685477[6-9]|92233720368547[8-9]|9223372036854[8-9]|922337203685[5-9]|92233720368[6-9]|92233720369|922337203[7-9]|92233720[4-9]|9223372[1-9]|922337[3-9]|92233[8-9]|9223[4-9]|922[4-9]|92[3-9]|9[3-9]

将这些[输出]添加到regex

(?!输出)''d{19}

将变为[output2]

(?!922337203685477580[8-9]|92233720368547758[1-9]|92233720368547759|922337203685477[6-9]|92233720368547[8-9]|9223372036854[8-9]|922337203685[5-9]|92233720368[6-9]|92233720369|922337203[7-9]|92233720[4-9]|9223372[1-9]|922337[3-9]|92233[8-9]|9223[4-9]|922[4-9]|92[3-9]|9[3-9])'d{19}

匹配'd{19}<=9223372036854775807

添加

^(?:9223372036854775808|-?(?:''d{0,18}|[output2])$

^(?:-9223372036854775808|-?(?:'d{0,18}|(?!922337203685477580[8-9]|92233720368547758[1-9]|92233720368547759|922337203685477[6-9]|92233720368547[8-9]|9223372036854[8-9]|922337203685[5-9]|92233720368[6-9]|92233720369|922337203[7-9]|92233720[4-9]|9223372[1-9]|922337[3-9]|92233[8-9]|9223[4-9]|922[4-9]|92[3-9]|9[3-9])'d{19}))$

将匹配

-9223372036854775808
+/-'d{0,18}
+/-'d{19}<=9223372036854775807

演示