From cd42545c7dd2b525bf1493650cbe347de6d409cb Mon Sep 17 00:00:00 2001 From: sunxyw <31698606+sunxyw@users.noreply.github.com> Date: Thu, 28 Apr 2022 21:50:48 +0800 Subject: [PATCH] refactor `match_pattern` implementation (#102) * refactor match_pattern implementation * add match_pattern escaped wildcards support * add match_pattern global function test --- src/ZM/global_functions.php | 16 +++------------- tests/ZM/GlobalFunctionsTest.php | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/ZM/global_functions.php b/src/ZM/global_functions.php index d943077b..ee192f4c 100644 --- a/src/ZM/global_functions.php +++ b/src/ZM/global_functions.php @@ -99,19 +99,9 @@ function unicode_decode(string $str): ?string */ function match_pattern(string $pattern, string $subject): bool { - if (empty($pattern) && empty($subject)) { - return true; - } - if (mb_strpos($pattern, '*') === 0 && mb_substr($pattern, 1, 1) !== '' && empty($subject)) { - return false; - } - if (mb_strpos($pattern, mb_substr($subject, 0, 1)) === 0) { - return match_pattern(mb_substr($pattern, 1), mb_substr($subject, 1)); - } - if (mb_strpos($pattern, '*') === 0) { - return match_pattern(mb_substr($pattern, 1), $subject) || match_pattern($pattern, mb_substr($subject, 1)); - } - return false; + $pattern = str_replace(['\*', '\\\\.*'], ['.*', '\*'], preg_quote($pattern, '/')); + $pattern = '/^' . $pattern . '$/i'; + return preg_match($pattern, $subject) === 1; } /** diff --git a/tests/ZM/GlobalFunctionsTest.php b/tests/ZM/GlobalFunctionsTest.php index a786995a..3e3a8600 100644 --- a/tests/ZM/GlobalFunctionsTest.php +++ b/tests/ZM/GlobalFunctionsTest.php @@ -40,4 +40,35 @@ class GlobalFunctionsTest extends TestCase }); $this->assertLessThan(0.1, $time); } + + /** + * @dataProvider providerTestMatchPattern + */ + public function testMatchPattern(string $pattern, string $subject, bool $expected): void + { + $this->assertEquals($expected, match_pattern($pattern, $subject)); + } + + public function providerTestMatchPattern(): array + { + return [ + 'empty' => ['', '', true], + 'empty subject' => ['foo', '', false], + 'empty pattern' => ['', 'foo', false], + 'simple' => ['foo', 'foo', true], + 'simple case insensitive' => ['FOO', 'foo', true], + 'simple case insensitive 2' => ['foo', 'FOO', true], + 'unicode' => ['föö', 'föö', true], + 'chinese' => ['中文', '中文', true], + 'wildcard' => ['foo*', 'foo', true], + 'wildcard 2' => ['foo*', 'foobar', true], + 'wildcard 3' => ['foo*bar', 'foo with bar', true], + 'wildcard 4' => ['foo*bar', 'foo but no bar with it', false], + 'wildcard with chinese' => ['中文*', '中文', true], + 'wildcard with chinese 2' => ['全世界*中国话', '全世界都在说中国话', true], + 'complex' => ['foo*bar*baz', 'foo with bar and baz', true], + 'regex' => ['[a-z]+', 'foo', false], // regex is not supported yet + 'escaped' => ['foo\\*bar', 'foo*bar', true], + ]; + } }