File: preg-match.php

package info (click to toggle)
php-composer-pcre 3.3.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 484 kB
  • sloc: php: 2,094; makefile: 19
file content (139 lines) | stat: -rw-r--r-- 5,073 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<?php

namespace PregMatchShapes;

use Composer\Pcre\Preg;
use Composer\Pcre\Regex;
use function PHPStan\Testing\assertType;

function doMatch(string $s): void
{
    if (Preg::match('/Price: /i', $s, $matches)) {
        assertType('array{string}', $matches);
    } else {
        assertType('array{}', $matches);
    }
    assertType('array{}|array{string}', $matches);

    if (Preg::match('/Price: (£|€)\d+/', $s, $matches)) {
        assertType('array{string, \'£\'|\'€\'}', $matches);
    } else {
        assertType('array{}', $matches);
    }
    assertType('array{}|array{string, \'£\'|\'€\'}', $matches);

    if (Preg::match('/Price: (£|€)?\d+/', $s, $matches)) {
        assertType('array{string, \'£\'|\'€\'|null}', $matches);
    } else {
        assertType('array{}', $matches);
    }
    assertType('array{}|array{string, \'£\'|\'€\'|null}', $matches);

    // passing the PREG_UNMATCHED_AS_NULL should change nothing compared to above as it is always set
    if (Preg::match('/Price: (£|€)?\d+/', $s, $matches, PREG_UNMATCHED_AS_NULL)) {
        assertType('array{string, \'£\'|\'€\'|null}', $matches);
    } else {
        assertType('array{}', $matches);
    }
    assertType('array{}|array{string, \'£\'|\'€\'|null}', $matches);

    if (Preg::isMatch('/Price: (?<currency>£|€)\d+/', $s, $matches)) {
        assertType('array{0: string, currency: \'£\'|\'€\', 1: \'£\'|\'€\'}', $matches);
    } else {
        assertType('array{}', $matches);
    }
    assertType('array{}|array{0: string, currency: \'£\'|\'€\', 1: \'£\'|\'€\'}', $matches);
}

function doMatchStrictGroups(string $s): void
{
    if (Preg::matchStrictGroups('/Price: /i', $s, $matches)) {
        assertType('array{string}', $matches);
    } else {
        assertType('array{}', $matches);
    }
    assertType('array{}|array{string}', $matches);

    if (Preg::matchStrictGroups('/Price: (£|€)\d+/', $s, $matches)) {
        assertType('array{string, \'£\'|\'€\'}', $matches);
    } else {
        assertType('array{}', $matches);
    }
    assertType('array{}|array{string, \'£\'|\'€\'}', $matches);

    if (Preg::isMatchStrictGroups('/Price: (?<test>£|€)\d+/', $s, $matches)) {
        assertType('array{0: string, test: \'£\'|\'€\', 1: \'£\'|\'€\'}', $matches);
    } else {
        assertType('array{}', $matches);
    }
    assertType('array{}|array{0: string, test: \'£\'|\'€\', 1: \'£\'|\'€\'}', $matches);
}

function doMatchStrictGroupsUnsafe(string $s): void
{
    if (Preg::isMatchStrictGroups('{Configure Command(?: *</td><td class="v">| *=> *)(.*)(?:</td>|$)}m', $s, $matches)) {
        // does not error because the match group might be empty but is not optional
        assertType('array{string, string}', $matches);
    }

    // should error as it is unsafe due to the optional group 1
    Regex::matchStrictGroups('{Configure Command(?: *</td><td class="v">| *=> *)(.*)?(?:</td>|$)}m', $s);

    if (Preg::matchAllStrictGroups('{((?<foo>.)?z)}m', $s, $matches)) {
        // should error as it is unsafe due to the optional group foo/2
    }

    if (Preg::isMatchStrictGroups('{'.$s.'}', $s, $matches)) {
        // should error as it is unsafe due not being introspectable with the dynamic string
    }
}

function doMatchAllStrictGroups(string $s): void
{
    if (Preg::matchAllStrictGroups('/Price: /i', $s, $matches)) {
        assertType('array{list<string>}', $matches);
    } else {
        assertType('array{}', $matches);
    }
    assertType('array{}|array{list<string>}', $matches);

    if (Preg::matchAllStrictGroups('/Price: (£|€)\d+/', $s, $matches)) {
        assertType('array{list<string>, list<\'£\'|\'€\'>}', $matches);
    } else {
        assertType('array{}', $matches);
    }
    assertType('array{}|array{list<string>, list<\'£\'|\'€\'>}', $matches);

    if (Preg::isMatchAllStrictGroups('/Price: (?<test>£|€)\d+/', $s, $matches)) {
        assertType('array{0: list<string>, test: list<\'£\'|\'€\'>, 1: list<\'£\'|\'€\'>}', $matches);
    } else {
        assertType('array{}', $matches);
    }
    assertType('array{}|array{0: list<string>, test: list<\'£\'|\'€\'>, 1: list<\'£\'|\'€\'>}', $matches);

    if (Preg::isMatchAllStrictGroups('/Price: (?<test>£|€)?\d+/', $s, $matches)) {
        assertType('array{0: list<string>, test: list<\'£\'|\'€\'>, 1: list<\'£\'|\'€\'>}', $matches);
    }
}

// disabled until https://github.com/phpstan/phpstan-src/pull/3185 can be resolved
//
//function identicalMatch(string $s): void
//{
//    if (Preg::match('/Price: /i', $s, $matches) === 1) {
//        assertType('array{string}', $matches);
//    } else {
//        assertType('array{}', $matches);
//    }
//    assertType('array{}|array{string}', $matches);
//}
//
//function equalMatch(string $s): void
//{
//    if (Preg::match('/Price: /i', $s, $matches) == 1) {
//        assertType('array{string}', $matches);
//    } else {
//        assertType('array{}', $matches);
//    }
//    assertType('array{}|array{string}', $matches);
//}