nimayneb / yawl
YAWL - 另一个通配符库 - 用于匹配带有星号 (*) 和查询标记 (?) 的字符串模式
2.2.0
2020-05-13 16:29 UTC
Requires
- php: ^7.4.0
- ext-mbstring: *
- nimayneb/benchmark: 1.0.1
- phpmd/phpmd: ^2.8
Requires (Dev)
- nimayneb/phpqg: 1.0.0
- phpunit/phpunit: ^9.1.0
This package is auto-updated.
Last update: 2024-09-25 20:46:39 UTC
README
这是一个包含用于任何通配符实现的类的库,用于查找带有 * (星号) 和 ? (查询) 标记的模式。
问题
在没有正则表达式扩展(名为 ext-pcre
- 在 PHP 5.3 之前)的情况下,PHP 中没有通配符支持。
参见 https://php.ac.cn/manual/en/pcre.installation.php。
已知的通配符行为(参见 通配符 (@维基百科))对于良好的实现是有限的。
一个小补救措施?
我们需要一种“编译”和“缓存”的模式的类型。正则表达式(如 preg_match
)的实现具有巨大的性能。从 PHP 7.0 开始,我们失去了这些优势,因为即时编译的 pcre 模式!
目录
- 基准测试
- 通配符变体
- 可能的合法模式
- 无效模式
- 转义
- 重复短语
- 缓存
- 愿望清单
- 附录
API
基准测试
当我们基准测试几种匹配合适短语的(1000个随机字符串)方法时,我们没有“正则表达式”的好结果
单字节
多字节(如 Unicode)
内部 PHP 函数比较
通配符变体
可能的合法模式
?? (2 characters)
???* (2-3 characters)
无效模式
***
?**
?*?
*?
转义
\\
\?
\*
请注意此转义场景
进一步解释
重复短语
星号(*
)在找到正确位置时存在问题。如果字符串中可以找到几个相同的短语,则必须在所有位置进行搜索以找到模式。
Search: *is?ue (where is "*is")
Subject: this is an asterisk issue
Founds: ^ ^ ^ ^
最简单的解决方案是递归地分解模式,但它不应该递归。
缓存
正则表达式扩展具有缓存和编译策略以提高性能。当第二次调用相同的模式时,性能会大幅提高。
为了帮助我们提高性能,我们使用简单的键值缓存。
protected array $cachedResults = [];
public function match(string $subject): bool
{
return $this->cachedResults[$subject] ?? $this->cachedResults[$subject] = $this->computePhrases($subject, 0);
}
这不是一个首选的解决方案。
愿望清单
- 移除
WildcardPerformer::computePhrases
的递归调用(参见 维基百科 - 匹配通配符) - 移除
StringFunctionMapper
(太慢) - 合并匹配器和执行者(一个优点)
- 缓存接口
- 新模式
??**
(0 或 2 个字符)或?????**
(0 或 5 个字符) - 全局支持
- 示例:
[abcdef0123456789]
,[0-9a-f]
,[!a-z]
- 在 YAWL 中的使用
[0-9a-f]?
(一次)[0-9a-f]?*
(零次或一次)[0-9a-f]*
(零次或 N 次)[0-9a-f]**
(一次或 N 次)[0-9a-f]x
(一次然后跟随x
)
- 示例:
附录
常见算法
非递归算法
递归算法
PDepend
- NOP - 包的数量
- NOC - 类的数量
- NOM - 方法数量
- LOC – 代码行数
- CYCLO - 圈复杂度
- CALLS - 独特函数和方法调用的数量
- ANDC - 平均派生类数量
- AHH - 平均层次高度