Completed
Pull Request — phoneNumberMatcher (#171)
by Joshua
23:58 queued 09:37
created

Matcher   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 95.08%

Importance

Changes 0
Metric Value
wmc 28
lcom 1
cbo 0
dl 0
loc 178
ccs 58
cts 61
cp 0.9508
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A groupCount() 0 8 2
A __construct() 0 5 1
B doMatch() 0 38 6
A matches() 0 4 1
A lookingAt() 0 4 1
A find() 0 10 2
A end() 0 10 4
A start() 0 11 4
A replaceFirst() 0 4 1
A replaceAll() 0 4 1
A reset() 0 6 1
A group() 0 7 4
1
<?php
2
3
namespace libphonenumber;
4
5
/**
6
 * Matcher for various regex matching
7
 *
8
 * Note that this is NOT the same as google's java PhoneNumberMatcher class.
9
 * This class is a minimal port of java's built-in matcher class, whereas PhoneNumberMatcher
10
 * is designed to recognize phone numbers embedded in any text.
11
 *
12
 * @internal
13
 */
14
class Matcher
15
{
16
    /**
17
     * @var string
18
     */
19
    protected $pattern;
20
21
    /**
22
     * @var string
23
     */
24
    protected $subject;
25
26
    /**
27
     * @var array
28
     */
29
    protected $groups = array();
30
31
    private $searchIndex = 0;
32
33
    /**
34
     * @param string $pattern
35
     * @param string $subject
36
     */
37 3109
    public function __construct($pattern, $subject)
38
    {
39 3109
        $this->pattern = str_replace('/', '\/', $pattern);
40 3109
        $this->subject = $subject;
41 3109
    }
42
43 3109
    protected function doMatch($type = 'find', $offset = 0)
44
    {
45 3109
        $final_pattern = '(?:' . $this->pattern . ')';
46
        switch ($type) {
47 3109
            case 'matches':
48 3082
                $final_pattern = '^' . $final_pattern . '$';
49 3082
                break;
50 3065
            case 'lookingAt':
51 3039
                $final_pattern = '^' . $final_pattern;
52 3039
                break;
53 3045
            case 'find':
54
            default:
55
                // no changes
56 3045
                break;
57
        }
58 3109
        $final_pattern = '/' . $final_pattern . '/ui';
59
60 3109
        $search = mb_substr($this->subject, $offset);
61
62 3109
        $result = preg_match($final_pattern, $search, $groups, PREG_OFFSET_CAPTURE);
63
64 3109
        if ($result === 1) {
65
            // Expand $groups into $this->groups, but being multi-byte aware
66
67 2695
            $positions = array();
68
69 2695
            foreach ($groups as $group) {
70 2695
                $positions[] = array(
71 2695
                    $group[0],
72 2695
                    $offset + mb_strlen(mb_strcut($search, 0, $group[1]))
73
                );
74
            }
75
76 2695
            $this->groups = $positions;
77
        }
78
79 3109
        return ($result === 1);
80
    }
81
82
    /**
83
     * @return bool
84
     */
85 3082
    public function matches()
86
    {
87 3082
        return $this->doMatch('matches');
88
    }
89
90
    /**
91
     * @return bool
92
     */
93 3039
    public function lookingAt()
94
    {
95 3039
        return $this->doMatch('lookingAt');
96
    }
97
98
    /**
99
     * @return bool
100
     */
101 3045
    public function find($offset = null)
102
    {
103 3045
        if ($offset === null) {
104 3044
            $offset = $this->searchIndex;
105
        }
106
107
        // Increment search index for the next time we call this
108 3045
        $this->searchIndex++;
109 3045
        return $this->doMatch('find', $offset);
110
    }
111
112
    /**
113
     * @return int
114
     */
115 141
    public function groupCount()
116
    {
117 141
        if (empty($this->groups)) {
118
            return null;
119
        } else {
120 141
            return count($this->groups) - 1;
121
        }
122
    }
123
124
    /**
125
     * @param int $group
126
     * @return string
127
     */
128 85
    public function group($group = null)
129
    {
130 85
        if (!isset($group) || $group === null) {
131 31
            $group = 0;
132
        }
133 85
        return (isset($this->groups[$group][0])) ? $this->groups[$group][0] : null;
134
    }
135
136
    /**
137
     * @param int|null $group
138
     * @return int
139
     */
140 303
    public function end($group = null)
141
    {
142 303
        if (!isset($group) || $group === null) {
143 303
            $group = 0;
144
        }
145 303
        if (!isset($this->groups[$group])) {
146
            return null;
147
        }
148 303
        return $this->groups[$group][1] + mb_strlen($this->groups[$group][0]);
149
    }
150
151 231
    public function start($group = null)
152
    {
153 231
        if (!isset($group) || $group === null) {
154 231
            $group = 0;
155
        }
156 231
        if (!isset($this->groups[$group])) {
157
            return null;
158
        }
159
160 231
        return $this->groups[$group][1];
161
    }
162
163
    /**
164
     * @param string $replacement
165
     * @return string
166
     */
167 64
    public function replaceFirst($replacement)
168
    {
169 64
        return preg_replace('/' . $this->pattern . '/x', $replacement, $this->subject, 1);
170
    }
171
172
    /**
173
     * @param string $replacement
174
     * @return string
175
     */
176 126
    public function replaceAll($replacement)
177
    {
178 126
        return preg_replace('/' . $this->pattern . '/x', $replacement, $this->subject);
179
    }
180
181
    /**
182
     * @param string $input
183
     * @return Matcher
184
     */
185 57
    public function reset($input = "")
186
    {
187 57
        $this->subject = $input;
188
189 57
        return $this;
190
    }
191
}
192