/ / Perché questo regex php non corrisponde a tutti gli input - php, regex

Perché questa espressione regolare di php non corrisponde a tutti gli input: php, regex

Perché la seguente regex: $regex = "/b(V|E)?d{1,2}? ?d{3} ?d{3}b/i"; non corrisponde a tutti gli input di seguito

Ho pensato che questo (V|E)?d{1,2}? ? renderebbe facoltative le lettere, il primo uno o due numeri e il primo spazio

<?php

$sms = array(
"test test test 11 111 111 test test test",
"test test test 1 111 111 test test test",
"test test test 111 111 test test test", // does not match
"test test test test test test 11111111",
"test test test 1111111 test test test",
"test test test 111111 test test test", // does not match
"test test test E11 111 111 test test test",
"test test test V1 111 111 test test test",
"test test test V111 111 test test test", // does not match
"test test test V11111111 test test test",
"test test test V1111111 test test test",
"test test test E111111 test test test", // does not match
"test test test V 11 111 111 test test test",
"test test test V 1 111 111 test test test",
"test test test E 111 111 test test test", // does not match
"test test test V 11111111 test test test",
"test test test V 1111111 test test test",
"test test test V 111111 test test test", //does not match
"test test test V11 111 111 test test test",
"test test test V1 111 111 test test test",
"test test test E111 111 test test test", //does not match
"test test test V11111111 test test test",
"V1111111 test test test  test test test",
"test test test V111111 test test test", // does not match
);

$regex = "/b(V|E)?d{1,2}? ?d{3} ?d{3}b/i";
$noMatches = 0;
$index = 0;
foreach($sms as $v) {
$match = preg_match($regex, $v, $matches);



if($match) {
//print_r($matches);
//echo "$v match!n";
//$matches++;
}
else {
echo "$index - $v does NOT match!n";
$noMatches++;
}
$index++;
}
$total = count($sms);
echo "nnTotal: $totalnNo Matches: $noMatchesn";

PRODUZIONE

$ php test-regex.php
2 - test test test 111 111 test test test does NOT match!
5 - test test test 111111 test test test does NOT match!
8 - test test test V111 111 test test test does NOT match!
11 - test test test E111111 test test test does NOT match!
14 - test test test E 111 111 test test test does NOT match!
17 - test test test V 111111 test test test does NOT match!
20 - test test test E111 111 test test test does NOT match!
23 - test test test V111111 test test test does NOT match!


Total: 24
No Matches: 8

MODIFICARE:

Usando il suggerimento di Mario, il regex è ora $regex = "/b(V|E)?d{0,2} ?d{3} ?d{3}b/i";, perché in alcuni casi, questa regex non cattura la lettera V o E

$output = array(
"test test test E11 111 111 test test test" => "E11 111 111",
"test test test V1 111 111 test test test" => "V1 111 111",
"test test test V111 111 test test test" => "V111 111",
"test test test V11111111 test test test" => "V11111111",
"test test test V1111111 test test test" => "V1111111",
"test test test E111111 test test test" => "E111111",
"test test test V 11 111 111 test test test" => "11 111 111", // Missing Letter
"test test test V 1 111 111 test test test" => "1 111 111", // Missing Leter
"test test test E 111 111 test test test" => "E 111 111",
"test test test V 11111111 test test test" => "11111111", // Missing Letter
"test test test V 1111111 test test test" => "1111111", // Missing Letter
"test test test V 111111 test test test" => "V 111111",
"test test test V11 111 111 test test test" => "V11 111 111",
"test test test V1 111 111 test test test" => "V1 111 111",
"test test test E111 111 test test test" => "E111 111",
"test test test V11111111 test test test" => "V11111111",
"V1111111 test test test  test test test" => "V1111111",
"test test test V111111 test test test" => "V111111",
"V 1111111 test test test" => "1111111", // Missing Letter
"test test test V 1111111 test test test" => "1111111", // Missing Letter
);

risposte:

2 per risposta № 1

? è solo un quantificatore dopo gruppi o caratteri letterali o classi di caratteri, ad es.

Se ? si verifica dopo un altro quantificatore * o + e {n,m} renderà la corrispondenza meno avida. Ciò significa che regex proverà a corrispondere alla quantità minima.

Così d{1,2}? non significa facoltativo. Significa abbinare uno o due, ma preferisce abbinarne solo uno. Volevi scrivere d{0,2} anziché.


1 per risposta № 2

Non corrispondono perché il regex richiede almeno 7 cifre in totale:

/b(V|E)?d{1,2}? ?d{3} ?d{3}b/
|        |      |
|        |      -------->  3 digits exactly
|        --------------->  3 digits exactly
------------------------>  1 or 2 digits (prefers 1, but will match
2 if there are 8 digits in a row)

Tutti gli ingressi difettosi sono brevi di una cifra.


1 per risposta № 3

Se si desidera rendere la prima parte completamente opzionale, è necessario racchiuderla tra parentesi e aggiungere a ? a tale. Puoi anche usare un gruppo di caratteri per V|E

(?:[VE]d{1,2} )?