1
|
|
|
<?php declare(strict_types=1); |
2
|
|
|
/** |
3
|
|
|
* Created by Vitaly Iegorov <[email protected]>. |
4
|
|
|
* on 06.04.17 at 07:28 |
5
|
|
|
*/ |
6
|
|
|
namespace samsonframework\stringconditiontree\string; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* This class describes string structure character group. |
10
|
|
|
* |
11
|
|
|
* @author Vitaly Egorov <[email protected]> |
12
|
|
|
*/ |
13
|
|
|
abstract class AbstractCG |
14
|
|
|
{ |
15
|
|
|
/** string Character group matching regexp pattern matching group name */ |
16
|
|
|
const PATTERN_GROUP = ''; |
17
|
|
|
|
18
|
|
|
/** string Regular expression matching character group */ |
19
|
|
|
const PATTERN_REGEXP = ''; |
20
|
|
|
|
21
|
|
|
/** string Character group matching regexp pattern */ |
22
|
|
|
const PATTERN = ''; |
23
|
|
|
|
24
|
|
|
/** @var int Character group length */ |
25
|
|
|
protected $length; |
26
|
|
|
|
27
|
|
|
/** @var string Character group string */ |
28
|
|
|
protected $string; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* AbstractCharacterGroup constructor. |
32
|
|
|
* |
33
|
|
|
* @param string $string Character group string |
34
|
|
|
* @param int $length Character group length |
35
|
|
|
*/ |
36
|
23 |
|
public function __construct(string $string, int $length = 0) |
37
|
|
|
{ |
38
|
23 |
|
$this->string = $string; |
39
|
23 |
|
$this->length = $length; |
40
|
23 |
|
} |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Create character group from input string. |
44
|
|
|
* |
45
|
|
|
* @param string $input Input string |
46
|
|
|
* |
47
|
|
|
* @return NullCG|AbstractCG|FixedCG|VariableCG Character group instance |
48
|
|
|
*/ |
49
|
19 |
|
public static function fromString(string &$input) |
50
|
|
|
{ |
51
|
19 |
|
if (preg_match('/^'.static::PATTERN.'/', $input, $matches)) { |
52
|
|
|
// Replace only first occurrence of character group |
53
|
19 |
|
if (($pos = strpos($input, $matches[0])) !== false) { |
54
|
19 |
|
$input = substr_replace($input, '', $pos, strlen($matches[0])); |
55
|
|
|
|
56
|
19 |
|
$className = static::class; |
57
|
19 |
|
return new $className($matches[static::PATTERN_GROUP], strlen($matches[static::PATTERN_GROUP])); |
58
|
|
|
} |
59
|
|
|
} |
60
|
|
|
|
61
|
17 |
|
return new NullCG(); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* @return bool True if character group is variable length otherwise false |
66
|
|
|
*/ |
67
|
1 |
|
public function isVariable(): bool |
68
|
|
|
{ |
69
|
1 |
|
return $this instanceof VariableCG; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Compare character groups. |
74
|
|
|
* |
75
|
|
|
* @param AbstractCG $group Compared character group |
76
|
|
|
* |
77
|
|
|
* @return int -1, 0, 1 Lower, equal, higher |
78
|
|
|
*/ |
79
|
14 |
View Code Duplication |
public function compare(AbstractCG $group): int |
|
|
|
|
80
|
|
|
{ |
81
|
|
|
// Equal character group types - return length comparison |
82
|
14 |
|
if ($this->isSameType($group)) { |
83
|
|
|
// Variable character groups with longer length has higher priority |
84
|
13 |
|
return $this->compareLength($group); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* Character groups are different: |
89
|
|
|
* Fixed character groups has higher priority, |
90
|
|
|
* variable character groups has lower priority |
91
|
|
|
*/ |
92
|
6 |
|
return $this->isFixed() ? 1 : -1; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Check if compared character group has same type. |
97
|
|
|
* |
98
|
|
|
* @param AbstractCG $group Compared character group |
99
|
|
|
* |
100
|
|
|
* @return bool True if character group has same type otherwise false |
101
|
|
|
*/ |
102
|
20 |
|
public function isSameType(AbstractCG $group): bool |
103
|
|
|
{ |
104
|
20 |
|
return get_class($group) === get_class($this); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Compare this character group length to compared character group length. |
109
|
|
|
* |
110
|
|
|
* @param AbstractCG $group Compared character group |
111
|
|
|
* |
112
|
|
|
* @return int -1, 0, 1 Character groups comparison result |
113
|
|
|
*/ |
114
|
|
|
abstract protected function compareLength(AbstractCG $group): int; |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* @return bool True if character group is fixed length otherwise false |
118
|
|
|
*/ |
119
|
7 |
|
public function isFixed(): bool |
120
|
|
|
{ |
121
|
7 |
|
return $this instanceof FixedCG; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Get two character groups longest common prefix. |
126
|
|
|
* |
127
|
|
|
* @param AbstractCG $group Compared character group |
128
|
|
|
* |
129
|
|
|
* @return string Longest common prefix or empty string |
130
|
|
|
*/ |
131
|
|
|
abstract public function getCommonPrefix(AbstractCG $group): string; |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* @return string Character group string |
135
|
|
|
*/ |
136
|
2 |
|
public function getString(): string |
137
|
|
|
{ |
138
|
2 |
|
return $this->string; |
139
|
|
|
} |
140
|
|
|
} |
141
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.