1.2.989. Possible Missing Subpattern¶
When capturing subpatterns are the last ones in a regex, PHP doesn’t fill their spot in the resulting array. This leads to a possible missing index in the result array. The same applies to preg_replace() : the pattern may match the string, but no value is available is the corresponding sub-pattern.
In PHP 7.4, a new option was added : PREG_UNMATCHED_AS_NULL
, which always provides a value for the subpatterns.
<?php
// displays a partial array, from 0 to 1
preg_match('/(a)(b)?/', 'adc', $r);
print_r($r);
/*
Array
(
[0] => a
[1] => a
)
*/
// displays a full array, from 0 to 2
preg_match('/(a)(b)?/', 'abc', $r);
print_r($r);
/*
Array
(
[0] => ab
[1] => a
[2] => b
)
*/
// double 'b' when it is found
print preg_replace(',^a(b)?,', './$1$1', 'abc'); // prints ./abbc
print preg_replace(',^a(b)?,', './$1$1', 'adc'); // prints ./dc
?>
See also Bug #73948 Preg_match_all should return NULLs on trailing optional capture groups. and Bug #50887 preg_match , last optional sub-patterns ignored when empty.
1.2.989.2. Connex PHP features¶
1.2.989.2.1. Suggestions¶
Add an always capturing subpatterns after the last ?
Move the ? inside the parenthesis, so the parenthesis is always on, but the content may be empty
Add a test on the last index of the resulting array, to ensure it is available when needed
Use the PREG_UNMATCHED_AS_NULL option (PHP 7.4+)
1.2.989.2.2. Specs¶
Short name |
Php/MissingSubpattern |
Rulesets |
|
Exakat since |
1.6.1 |
PHP Version |
All |
Severity |
Minor |
Time To Fix |
Quick (30 mins) |
Precision |
Very high |
Examples |
|
Available in |