nimayneb / wildcard-trait
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-14 21:16:05 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
的递归调用(见 Wikipedia - 匹配通配符) - 移除
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)