鉴于一个巨大的列表(超过一千个随机数字从00001到60031),匹配每个数字和只有那些数字的最佳方法是什么。
列表00001,00002,00003,00004,00006,00010,00016,00030,00039,00177,00187,00219,00239,00240,00241,00242,00245,00248,00250,00258,00260,....,20065,20069,20070,...,27005,27007,28006,29000,29400,30100,......
我知道我可以用超长的蛮力强迫它陈述,也许还有一些技巧,比如范围0000[1-6]
,但还有什么更聪明的东西吗?是的我知道我可以把它放在像python这样的脚本中,或者像数据库一样,并相应地匹配它但我必须在正则表达式中这样做,因为系统是以这种方式构建的。
到目前为止:(0000[1-46])|0001[06]|0003[09]|001[78]7|002[136]9|0024[0-58]|....
答案 0 :(得分:1)
获取此应用http://www.regexformat.com,然后从工具菜单中运行
Strings to Regex - Ternary tree
。
将整个列表(数千)放入输入框,选择逗号作为分隔符
然后生成。
它将创建一个正则表达式,只需少于5步即可找到任何数字
在列表中非常快。
Screenshot和示例字符串175,000 word Dictionary
这些数字不过是你要搜索的单词。
您提供的示例中的正则表达式:
(?<!\d)(?:00(?:0(?:0(?:1|2|3|4|6)|1(?:0|6)|3(?:0|9))|1(?:77|87)|2(?:19|39|4(?:0|1|2|5|8)|5(?:0|8)|60))|2(?:00(?:6(?:5|9)|70)|700(?:5|7)|8006|9(?:000|400))|30100)(?!\d)
扩展
(?<! \d )
(?:
00
(?:
0
(?:
0
(?: 1 | 2 | 3 | 4 | 6 )
| 1
(?: 0 | 6 )
| 3
(?: 0 | 9 )
)
| 1
(?: 77 | 87 )
| 2
(?:
19
| 39
| 4
(?: 0 | 1 | 2 | 5 | 8 )
| 5
(?: 0 | 8 )
| 60
)
)
| 2
(?:
00
(?:
6
(?: 5 | 9 )
| 70
)
| 700
(?: 5 | 7 )
| 8006
| 9
(?: 000 | 400 )
)
| 30100
)
(?! \d )
编辑
添加Benchmark样本以测试效果。
显示使用带有/不带边界的正则表达式的结果:
请注意,几乎所有使用三元树生成的完整trie正则表达式
会有同样的替补,内容太多无关紧要。
Regex1: (?<!\d)(?:00(?:0(?:0(?:1|2|3|4|6)|1(?:0|6)|3(?:0|9))|1(?:77|87)|2(?:19|39|4(?:0|1|2|5|8)|5(?:0|8)|60))|2(?:00(?:6(?:5|9)|70)|700(?:5|7)|8006|9(?:000|400))|30100)(?!\d)
Options: < none >
Completed iterations: 50 / 50 ( x 1000 )
Matches found per iteration: 30
Elapsed Time: 1.75 s, 1747.23 ms, 1747235 µs
Regex2: (?:00(?:0(?:0(?:1|2|3|4|6)|1(?:0|6)|3(?:0|9))|1(?:77|87)|2(?:19|39|4(?:0|1|2|5|8)|5(?:0|8)|60))|2(?:00(?:6(?:5|9)|70)|700(?:5|7)|8006|9(?:000|400))|30100)
Options: < none >
Completed iterations: 50 / 50 ( x 1000 )
Matches found per iteration: 30
Elapsed Time: 1.13 s, 1129.65 ms, 1129650 µs
(50,000 iter) * (30 matches/iter) = 1,500,000 matches
-------------------------------------------------------------------------------------
Regex1 with boundary: 1,500,000 matches / 1.75 seconds = 857,143 matches/second
Regex2 no boundary: 1,500,000 matches / 1.13 seconds = 1,327,434 matches/second
答案 1 :(得分:0)
试试这个......
^(?:[0-5][0-9]{4}|600[0-2][0-9]|6003[01])(?<!00000)$
非捕获组中的第一个替代品通过匹配正好5个数字来捕获大多数数字,要求第一个数字为5或更小(请注意,这与00000匹配)。 接下来的两个交替使用60000-60031。 第二组是负面的后视,并且排除00000否则将匹配。
根据您使用的技术,负面外观可能不是一种选择。 PHP和python我相信支持它和Java肯定会... JavaScript我认为不是,但也许你可以通过二次检查检查一个值?