onerror
onerror

Reputation: 616

Why preg_match returns some empty elements?

I've written the regexp ^(?:([1-5])|([1-5]) .*|.* ([1-5])|.* ([1-5]) .*)$ to match either standalone digit 1-5, or a digit separated by at least one space form the rest of the string. I've tested it in online services and the result is the digit itself. However, when using code

preg_match('/^(?:([1-5])|([1-5]) .*|.* ([1-5])|.* ([1-5]) .*)$/', 'order 12314124 5', $matches);

I get this:

Array ( [0] => order 12314124 5 [1] => [2] => [3] => 5 )

The [0] element is a full match which is good. I anticipated the [1] element be 5 but it's empty, and there's another empty element. Why these empty elements appear?

Upvotes: 6

Views: 318

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626747

If you used the regex at regex101.com, all non-participating (i.e. those that did not match) groups are hidden. You can turn them on in options:

enter image description here

And you will see them:

enter image description here

A quick fix is to use a branch reset (?|...) instead of a non-capturing group (?:...) and access the $matches[1] value:

preg_match('/^(?|([1-5])|([1-5]) .*|.* ([1-5])|.* ([1-5]) .*)$/', 'order 12314124 5', $matches);
print_r($matches[1]); // => 5

See the IDEONE demo

Upvotes: 3

Related Questions