diff --git a/4dev/tests/CoreLibsConvertStringsTest.php b/4dev/tests/CoreLibsConvertStringsTest.php index 7270ec2a..90415d20 100644 --- a/4dev/tests/CoreLibsConvertStringsTest.php +++ b/4dev/tests/CoreLibsConvertStringsTest.php @@ -49,6 +49,24 @@ final class CoreLibsConvertStringsTest extends TestCase null, '12-34' ], + 'string format trailing match' => [ + '1234', + '2-2-', + null, + '12-34' + ], + 'string format leading match' => [ + '1234', + '-2-2', + null, + '12-34' + ], + 'string format double inside match' => [ + '1234', + '2--2', + null, + '12--34', + ], 'string format short first' => [ '1', '2-2', @@ -109,6 +127,12 @@ final class CoreLibsConvertStringsTest extends TestCase null, 'あいうえ' ], + 'mutltibyte split string' => [ + '1234', + '2-2', + null, + '1234' + ], ]; } @@ -148,6 +172,90 @@ final class CoreLibsConvertStringsTest extends TestCase $output ); } + + /** + * Undocumented function + * + * @return array + */ + public function countSplitPartsProvider(): array + { + return [ + '0 elements' => [ + '', + null, + 0 + ], + '1 element' => [ + '1', + null, + 1, + ], + '2 elements, trailing' => [ + '1-2-', + null, + 2 + ], + '2 elements, leading' => [ + '-1-2', + null, + 2 + ], + '2 elements, midde double' => [ + '1--2', + null, + 2 + ], + '4 elements' => [ + '1-2-3-4', + null, + 4 + ], + '3 elemenst, other splitter' => [ + '2-3_3', + '-_', + 3 + ], + 'illegal splitter' => [ + 'あsdf', + null, + 0 + ] + ]; + } + + /** + * count split parts + * + * @covers ::countSplitParts + * @dataProvider countSplitPartsProvider + * @testdox countSplitParts $input with splitters $split_characters will be $expected [$_dataName] + * + * @param string $input + * @param string|null $split_characters + * @param int $expected + * @return void + */ + public function testCountSplitParts( + string $input, + ?string $split_characters, + int $expected + ): void { + if ($split_characters === null) { + $output = \CoreLibs\Convert\Strings::countSplitParts( + $input + ); + } else { + $output = \CoreLibs\Convert\Strings::countSplitParts( + $input, + $split_characters + ); + } + $this->assertEquals( + $expected, + $output + ); + } } // __END__ diff --git a/www/admin/class_test.strings.php b/www/admin/class_test.strings.php index 23b26075..ff3f6168 100644 --- a/www/admin/class_test.strings.php +++ b/www/admin/class_test.strings.php @@ -68,7 +68,15 @@ print "Convert: $string with $split to: " . \CoreLibs\Convert\Strings::splitFormatString($string, $split) . "
"; - +$test_splits = [ + '', + '2', + '2-2', + '2-3-4', +]; +foreach ($test_splits as $split) { + print "$split with count: " . \CoreLibs\Convert\Strings::countSplitParts($split) . "
"; +} // error message print $log->printErrorMsg(); diff --git a/www/lib/CoreLibs/Convert/Strings.php b/www/lib/CoreLibs/Convert/Strings.php index 09a99756..1627f234 100644 --- a/www/lib/CoreLibs/Convert/Strings.php +++ b/www/lib/CoreLibs/Convert/Strings.php @@ -10,6 +10,38 @@ namespace CoreLibs\Convert; class Strings { + /** + * return the elements in the split list + * 0 if nothing / invalid split + * 1 if no split character found + * + * @param string $split_format + * @param string $split_characters + * @return int + */ + public static function countSplitParts( + string $split_format, + string $split_characters = '-' + ): int { + if ( + empty($split_format) || + // non valid characters inside, abort + !preg_match("/^[0-9" . $split_characters . "]/", $split_format) || + preg_match('/[^\x20-\x7e]/', $split_characters) + ) { + return 0; + } + $split_list = preg_split( + // allowed split characters + "/([" . $split_characters . "]{1})/", + $split_format + ); + if (!is_array($split_list)) { + return 0; + } + return count(array_filter($split_list)); + } + /** * split format a string base on a split format string * split format string is eg @@ -31,18 +63,19 @@ class Strings string $split_format, string $split_characters = '-' ): string { - // abort if split format is empty - if (empty($split_format)) { + if ( + // abort if split format is empty + empty($split_format) || + // if not in the valid ASCII character range for any of the strings + preg_match('/[^\x20-\x7e]/', $value) || + // preg_match('/[^\x20-\x7e]/', $split_format) || + preg_match('/[^\x20-\x7e]/', $split_characters) || + // only numbers and split characters in split_format + !preg_match("/[0-9" . $split_characters . "]/", $split_format) + ) { return $value; } - // if not in the valid ASCII character range - // might need some tweaking - if (preg_match('/[^\x20-\x7e]/', $value)) { - return $value; - } - // if (!mb_check_encoding($value, 'ASCII')) { - // return $value; - // } + // split format list $split_list = preg_split( // allowed split characters "/([" . $split_characters . "]{1})/", @@ -65,7 +98,7 @@ class Strings } $out .= $_part; $pos += (int)$offset; - } else { + } elseif ($pos) { // if first, do not add $out .= $offset; $last_split = $offset; }