Advertisement
rplantiko

Extract regex from list of numbers

Apr 16th, 2019
519
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 4.66 KB | None | 0 0
  1. # Eine Liste von Zahlen gleicher Länge (Postleitzahlen)
  2. # zu einem regulären Ausdruck zusammenfassen,
  3. # der eine Obermenge der Zahlen gemäß ihrer Ziffernverteilung repräsentiert
  4. # die unten folgende Liste gibt z.B. den regex
  5. #
  6. #    [5-6][0-7]\d\d
  7. #
  8. # Die Idee ist verfeinerbar:
  9. # für alle einzelnen Ziffern in jeder Position absteigen
  10. # "wenn es sich lohnt", d.h. für einzelne Ziffern eine "seltene" Kombination vorkommt:
  11. # diese in eine Alternierung aufnehmen ...|...
  12.  
  13. use strict;
  14. use warnings;
  15. use v5.28;
  16. use Carp::Assert;
  17. use List::Util qw(all);
  18. use Set::Light;
  19.  
  20. my @plz = (<DATA>);
  21. chomp @plz;
  22.  
  23. my $result = regexify( \@plz );
  24. say $result;
  25.  
  26. # Collect the set of digits in each place
  27. sub regexify {
  28.   my @array = @{ shift() };
  29.   my $length = length( $array[0] );
  30.   assert all { length == $length } @array;
  31.   my @digitSets = map { Set::Light->new() } (1..$length);
  32.   for my $w (@array) {
  33.     for my $i (0..$length-1) {
  34.       $digitSets[$i]->insert( substr( $w, $i, 1) );
  35.     }
  36.   }
  37.   my $result = "";
  38.   for my $s (@digitSets) {
  39.     $result .= simplify( join '',sort keys %$s);
  40.   }
  41.   return $result;
  42. }
  43.  
  44. # This serves only to prettify the result, replacing e.g. [5678] by [5-8]
  45. sub simplify {
  46.   my @digits = split '',shift;
  47.   assert all { $digits[$_] > $digits[$_-1] } (1..$#digits);
  48.  
  49.   my @stack = ([-1,-1]);
  50.   my $low  = sub : lvalue { $stack[-1]->[0] };
  51.   my $high = sub : lvalue { $stack[-1]->[1] };
  52.   for my $d (@digits) {
  53.     my ($l,$h) = (&$low(),&$high());
  54.     if ($l == -1) {
  55.       &$low() = $d;
  56.     } elsif ($h == -1) {
  57.        if ($l == $d - 1) {
  58.          &$high() = $d;
  59.        } else {
  60.         push @stack, [$d,-1];
  61.        }
  62.     } elsif ($h == $d - 1) {
  63.       &$high() = $d;
  64.     } else {
  65.       push @stack, [$d,-1];
  66.     }
  67.   }
  68.  
  69.   my $result = join '',map {
  70.     $_->[1] == -1 ?
  71.       $_->[0] :
  72.         ($_->[0] == 0 and $_->[1] == 9) ?
  73.           "\\d" :
  74.           "[$_->[0]-$_->[1]]"
  75.   } @stack;
  76.   return $result;
  77. }
  78.  
  79. __DATA__
  80. 5000
  81. 5001
  82. 5004
  83. 5010
  84. 5012
  85. 5013
  86. 5014
  87. 5015
  88. 5017
  89. 5018
  90. 5022
  91. 5023
  92. 5024
  93. 5025
  94. 5026
  95. 5027
  96. 5028
  97. 5032
  98. 5033
  99. 5034
  100. 5035
  101. 5036
  102. 5037
  103. 5040
  104. 5042
  105. 5043
  106. 5044
  107. 5046
  108. 5053
  109. 5054
  110. 5056
  111. 5057
  112. 5058
  113. 5062
  114. 5063
  115. 5064
  116. 5070
  117. 5072
  118. 5073
  119. 5074
  120. 5075
  121. 5076
  122. 5077
  123. 5078
  124. 5079
  125. 5080
  126. 5082
  127. 5083
  128. 5084
  129. 5085
  130. 5102
  131. 5103
  132. 5105
  133. 5106
  134. 5107
  135. 5108
  136. 5112
  137. 5113
  138. 5116
  139. 5200
  140. 5201
  141. 5210
  142. 5212
  143. 5213
  144. 5222
  145. 5223
  146. 5224
  147. 5225
  148. 5232
  149. 5233
  150. 5234
  151. 5235
  152. 5236
  153. 5237
  154. 5242
  155. 5243
  156. 5244
  157. 5245
  158. 5246
  159. 5272
  160. 5273
  161. 5274
  162. 5275
  163. 5276
  164. 5277
  165. 5300
  166. 5301
  167. 5303
  168. 5304
  169. 5305
  170. 5306
  171. 5312
  172. 5313
  173. 5314
  174. 5315
  175. 5316
  176. 5317
  177. 5318
  178. 5322
  179. 5323
  180. 5324
  181. 5325
  182. 5326
  183. 5330
  184. 5332
  185. 5333
  186. 5334
  187. 5400
  188. 5401
  189. 5402
  190. 5404
  191. 5405
  192. 5406
  193. 5408
  194. 5412
  195. 5413
  196. 5415
  197. 5416
  198. 5417
  199. 5420
  200. 5423
  201. 5425
  202. 5426
  203. 5430
  204. 5431
  205. 5432
  206. 5436
  207. 5442
  208. 5443
  209. 5444
  210. 5445
  211. 5452
  212. 5453
  213. 5454
  214. 5462
  215. 5463
  216. 5464
  217. 5465
  218. 5466
  219. 5467
  220. 5502
  221. 5503
  222. 5504
  223. 5505
  224. 5506
  225. 5507
  226. 5510
  227. 5512
  228. 5522
  229. 5524
  230. 5525
  231. 5600
  232. 5601
  233. 5603
  234. 5604
  235. 5605
  236. 5606
  237. 5607
  238. 5608
  239. 5610
  240. 5611
  241. 5612
  242. 5613
  243. 5614
  244. 5615
  245. 5616
  246. 5617
  247. 5618
  248. 5619
  249. 5620
  250. 5621
  251. 5622
  252. 5623
  253. 5624
  254. 5625
  255. 5626
  256. 5627
  257. 5628
  258. 5630
  259. 5632
  260. 5634
  261. 5636
  262. 5637
  263. 5642
  264. 5643
  265. 5644
  266. 5645
  267. 5646
  268. 5647
  269. 5702
  270. 5703
  271. 5704
  272. 5705
  273. 5706
  274. 5707
  275. 5708
  276. 5712
  277. 5722
  278. 5723
  279. 5724
  280. 5725
  281. 5726
  282. 5727
  283. 5728
  284. 5732
  285. 5733
  286. 5734
  287. 5735
  288. 5736
  289. 5737
  290. 5742
  291. 5745
  292. 5746
  293. 6000
  294. 6002
  295. 6003
  296. 6004
  297. 6005
  298. 6006
  299. 6007
  300. 6008
  301. 6009
  302. 6010
  303. 6011
  304. 6012
  305. 6013
  306. 6014
  307. 6015
  308. 6016
  309. 6017
  310. 6018
  311. 6019
  312. 6020
  313. 6021
  314. 6022
  315. 6023
  316. 6024
  317. 6025
  318. 6026
  319. 6027
  320. 6028
  321. 6030
  322. 6031
  323. 6032
  324. 6033
  325. 6034
  326. 6035
  327. 6036
  328. 6037
  329. 6038
  330. 6039
  331. 6042
  332. 6043
  333. 6044
  334. 6045
  335. 6047
  336. 6048
  337. 6052
  338. 6053
  339. 6055
  340. 6056
  341. 6060
  342. 6061
  343. 6062
  344. 6063
  345. 6064
  346. 6066
  347. 6067
  348. 6068
  349. 6072
  350. 6073
  351. 6074
  352. 6078
  353. 6102
  354. 6103
  355. 6105
  356. 6106
  357. 6110
  358. 6112
  359. 6113
  360. 6114
  361. 6122
  362. 6123
  363. 6125
  364. 6126
  365. 6130
  366. 6132
  367. 6133
  368. 6142
  369. 6143
  370. 6144
  371. 6145
  372. 6146
  373. 6147
  374. 6152
  375. 6153
  376. 6154
  377. 6156
  378. 6160
  379. 6161
  380. 6162
  381. 6163
  382. 6166
  383. 6167
  384. 6170
  385. 6173
  386. 6174
  387. 6182
  388. 6192
  389. 6196
  390. 6197
  391. 6203
  392. 6204
  393. 6205
  394. 6206
  395. 6207
  396. 6208
  397. 6210
  398. 6211
  399. 6212
  400. 6213
  401. 6214
  402. 6215
  403. 6216
  404. 6217
  405. 6218
  406. 6221
  407. 6222
  408. 6231
  409. 6232
  410. 6233
  411. 6234
  412. 6235
  413. 6236
  414. 6242
  415. 6243
  416. 6244
  417. 6245
  418. 6246
  419. 6247
  420. 6248
  421. 6252
  422. 6253
  423. 6260
  424. 6262
  425. 6263
  426. 6264
  427. 6265
  428. 6274
  429. 6275
  430. 6276
  431. 6277
  432. 6280
  433. 6281
  434. 6283
  435. 6284
  436. 6285
  437. 6286
  438. 6287
  439. 6288
  440. 6289
  441. 6294
  442. 6295
  443. 6300
  444. 6301
  445. 6302
  446. 6303
  447. 6304
  448. 6310
  449. 6312
  450. 6313
  451. 6314
  452. 6315
  453. 6317
  454. 6318
  455. 6319
  456. 6330
  457. 6331
  458. 6332
  459. 6333
  460. 6340
  461. 6341
  462. 6342
  463. 6343
  464. 6344
  465. 6345
  466. 6346
  467. 6349
  468. 6353
  469. 6354
  470. 6356
  471. 6362
  472. 6363
  473. 6365
  474. 6370
  475. 6371
  476. 6372
  477. 6373
  478. 6374
  479. 6375
  480. 6376
  481. 6377
  482. 6382
  483. 6383
  484. 6386
  485. 6387
  486. 6388
  487. 6390
  488. 6391
  489. 6402
  490. 6403
  491. 6404
  492. 6405
  493. 6410
  494. 6414
  495. 6415
  496. 6416
  497. 6417
  498. 6418
  499. 6422
  500. 6423
  501. 6424
  502. 6430
  503. 6431
  504. 6432
  505. 6433
  506. 6434
  507. 6436
  508. 6438
  509. 6440
  510. 6441
  511. 6442
  512. 6443
  513. 6452
  514. 6454
  515. 6460
  516. 6461
  517. 6462
  518. 6463
  519. 6464
  520. 6465
  521. 6466
  522. 6467
  523. 6468
  524. 6469
  525. 6472
  526. 6473
  527. 6474
  528. 6475
  529. 6476
  530. 6482
  531. 6484
  532. 6485
  533. 6487
  534. 6490
  535. 6491
  536. 6493
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement