Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
declare(strict_types=1);
4
 
5
namespace libphonenumber;
6
 
7
/**
8
 * Matcher for various regex matching
9
 *
10
 * Note that this is NOT the same as Google's java PhoneNumberMatcher class.
11
 * This class is a minimal port of java's built-in matcher class, whereas PhoneNumberMatcher
12
 * is designed to recognize phone numbers embedded in any text.
13
 *
14
 * @internal
15
 */
16
class Matcher
17
{
18
    protected string $pattern;
19
    protected string $subject = '';
20
 
21
    /**
22
     * @var array<array{string,int}>
23
     */
24
    protected array $groups = [];
25
 
26
    private int $searchIndex = 0;
27
 
28
    /**
29
     */
30
    public function __construct(string $pattern, string $subject)
31
    {
32
        $this->pattern = str_replace('/', '\/', $pattern);
33
        $this->subject = $subject;
34
    }
35
 
36
    /**
37
     */
38
    protected function doMatch(string $type = 'find', int $offset = 0): bool
39
    {
40
        $final_pattern = '(?:' . $this->pattern . ')';
41
        switch ($type) {
42
            case 'matches':
43
                $final_pattern = '^' . $final_pattern . '$';
44
                break;
45
            case 'lookingAt':
46
                $final_pattern = '^' . $final_pattern;
47
                break;
48
            case 'find':
49
            default:
50
                // no changes
51
                break;
52
        }
53
        $final_pattern = '/' . $final_pattern . '/ui';
54
 
55
        $search = mb_substr($this->subject, $offset);
56
 
57
        $result = preg_match($final_pattern, $search, $groups, PREG_OFFSET_CAPTURE);
58
 
59
        if ($result === 1) {
60
            // Expand $groups into $this->groups, but being multi-byte aware
61
 
62
            $positions = [];
63
 
64
            foreach ($groups as $group) {
65
                $positions[] = [
66
                    $group[0],
67
                    $offset + mb_strlen(substr($search, 0, $group[1])),
68
                ];
69
            }
70
 
71
            $this->groups = $positions;
72
        }
73
 
74
        return ($result === 1);
75
    }
76
 
77
    public function matches(): bool
78
    {
79
        return $this->doMatch('matches');
80
    }
81
 
82
    public function lookingAt(): bool
83
    {
84
        return $this->doMatch('lookingAt');
85
    }
86
 
87
    public function find(?int $offset = null): bool
88
    {
89
        if ($offset === null) {
90
            $offset = $this->searchIndex;
91
        }
92
 
93
        // Increment search index for the next time we call this
94
        $this->searchIndex++;
95
        return $this->doMatch('find', $offset);
96
    }
97
 
98
    public function groupCount(): ?int
99
    {
100
        if (empty($this->groups)) {
101
            return null;
102
        }
103
 
104
        return count($this->groups) - 1;
105
    }
106
 
107
    public function group(?int $group = null): ?string
108
    {
109
        if ($group === null) {
110
            $group = 0;
111
        }
112
        return $this->groups[$group][0] ?? null;
113
    }
114
 
115
    public function end(?int $group = null): ?int
116
    {
117
        if ($group === null) {
118
            $group = 0;
119
        }
120
        if (!isset($this->groups[$group])) {
121
            return null;
122
        }
123
        return $this->groups[$group][1] + mb_strlen($this->groups[$group][0]);
124
    }
125
 
126
    public function start(int $group = 0): ?int
127
    {
128
        if (!isset($this->groups[$group])) {
129
            return null;
130
        }
131
 
132
        return $this->groups[$group][1];
133
    }
134
 
135
    public function replaceFirst(string $replacement): string
136
    {
137
        return preg_replace('/' . $this->pattern . '/x', $replacement, $this->subject, 1);
138
    }
139
 
140
    public function replaceAll(string $replacement): string
141
    {
142
        return preg_replace('/' . $this->pattern . '/x', $replacement, $this->subject);
143
    }
144
 
145
    public function reset(string $input = ''): self
146
    {
147
        $this->subject = $input;
148
 
149
        return $this;
150
    }
151
}