Skip to content

preg_match optional named match groups are empty string when no match #11479

@kamil-zacek

Description

@kamil-zacek

Bug report

When there is a preg_match pattern like

~^(?P<dateFrom>\d)?\-?(?P<dateTo>\d)?$~

where is optional (because of ? after group) current array shape matcher resolve that there is a dumped type

Dumped type: array{0?: string, dateFrom?: numeric-string, 1?: numeric-string, dateTo?: numeric-string, 2?: numeric-string}

but expected output should be according to me

Dumped type: array{0?: string, dateFrom?: numeric-string|'', 1?: numeric-string|'', dateTo?: numeric-string, 2?: numeric-string}

https://phpstan.org/r/c025077a-7aa9-48f6-9a80-57148aa8036c

If I understand it well - problem is that when current array shape matcher resolve that matched group can be number only, it resolve that this is numeric-string. But does not recognise that when this is optional match group, this can be even empty string if this is not the last optional group in the pattern. (It means that 2 and date-to cannot be empty string because it is the last and if there is no match, this indices are not in the result anymore).

Code snippet that reproduces the problem

https://phpstan.org/r/c025077a-7aa9-48f6-9a80-57148aa8036c

Expected output

Dumped type: array{0?: string, dateFrom?: numeric-string|'', 1?: numeric-string|'', dateTo?: numeric-string, 2?: numeric-string}

Did PHPStan help you today? Did it make you happy in any way?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions