Add parseCharacterRanges function to Strings.php and tests
Parses character ranges like A-Z into individual characters and returns as an array
This commit is contained in:
@@ -140,6 +140,27 @@ $preg_error = Strings::isValidRegex($regex_string);
|
||||
print "[B] LAST PREGE ERROR: " . preg_last_error() . " -> "
|
||||
. Strings::getLastRegexErrorString() . " -> " . preg_last_error_msg() . "<br>";
|
||||
|
||||
$base_strings = [
|
||||
'A-Z',
|
||||
'a-z',
|
||||
'A-Za-z',
|
||||
'A-Df-g',
|
||||
'A-D0-9',
|
||||
'D-A7-0',
|
||||
'A-FB-G',
|
||||
'0-9',
|
||||
'あ-お',
|
||||
'ア-オ',
|
||||
];
|
||||
foreach ($base_strings as $string) {
|
||||
try {
|
||||
$parsed = Strings::parseCharacterRanges($string);
|
||||
print "Parsed ranges for '$string': " . DgS::printAr($parsed) . "<br>";
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
print "Error parsing ranges for '$string': " . $e->getMessage() . "<br>";
|
||||
}
|
||||
}
|
||||
|
||||
print "</body></html>";
|
||||
|
||||
// __END__
|
||||
|
||||
@@ -268,6 +268,51 @@ class Strings
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Split up character ranges in format A-Z, a-z, 0-9
|
||||
*
|
||||
* @param string $input
|
||||
* @return string[]
|
||||
*/
|
||||
public static function parseCharacterRanges(string $input): array
|
||||
{
|
||||
// if not alphanumeric, throw value error
|
||||
if (!preg_match("/^[A-Za-z0-9\-\s]+$/u", $input)) {
|
||||
throw new \InvalidArgumentException(
|
||||
"The input string contains invalid characters, "
|
||||
. "only alphanumeric, dash (-), space and 'or' are allowed: "
|
||||
. $input
|
||||
);
|
||||
}
|
||||
// Remove all spaces
|
||||
$input = str_replace(' ', '', $input);
|
||||
$result = [];
|
||||
// Find all patterns like "A-Z" (character-dash-character)
|
||||
preg_match_all('/(.)-(.)/u', $input, $matches, PREG_SET_ORDER);
|
||||
foreach ($matches as $match) {
|
||||
$start = $match[1];
|
||||
$end = $match[2];
|
||||
// Get ASCII/Unicode values
|
||||
$startOrd = ord($start[0]);
|
||||
$endOrd = ord($end[0]);
|
||||
// make sure start is before end
|
||||
if ($startOrd > $endOrd) {
|
||||
[$startOrd, $endOrd] = [$endOrd, $startOrd];
|
||||
}
|
||||
|
||||
// Generate range of characters
|
||||
for ($i = $startOrd; $i <= $endOrd; $i++) {
|
||||
$char = chr($i);
|
||||
if (!in_array($char, $result)) {
|
||||
$result[] = $char;
|
||||
}
|
||||
}
|
||||
}
|
||||
// make the result unique
|
||||
$result = array_unique($result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a regex is valid. Does not return the detail regex parser error
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user