nimayneb/yawl

YAWL - 另一个通配符库 - 用于匹配带有星号 (*) 和查询标记 (?) 的字符串模式

2.2.0 2020-05-13 16:29 UTC

This package is auto-updated.

Last update: 2024-09-25 20:46:39 UTC


README

Build Status

这是一个包含用于任何通配符实现的类的库,用于查找带有 * (星号) 和 ? (查询) 标记的模式。

问题

在没有正则表达式扩展(名为 ext-pcre - 在 PHP 5.3 之前)的情况下,PHP 中没有通配符支持。

参见 https://php.ac.cn/manual/en/pcre.installation.php

已知的通配符行为(参见 通配符 (@维基百科))对于良好的实现是有限的。

一个小补救措施?

我们需要一种“编译”和“缓存”的模式的类型。正则表达式(如 preg_match)的实现具有巨大的性能。从 PHP 7.0 开始,我们失去了这些优势,因为即时编译的 pcre 模式!

目录

  1. 基准测试
  2. 通配符变体
  3. 可能的合法模式
  4. 无效模式
  5. 转义
  6. 重复短语
  7. 缓存
  8. 愿望清单
  9. 附录

API

  1. 匹配器(用于单次调用)
  2. 执行者(用于多次调用)
  3. 转换器(用于正则表达式)

基准测试

当我们基准测试几种匹配合适短语的(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

Build Status

  • NOP - 包的数量
  • NOC - 类的数量
  • NOM - 方法数量
  • LOC – 代码行数
  • CYCLO - 圈复杂度
  • CALLS - 独特函数和方法调用的数量
  • ANDC - 平均派生类数量
  • AHH - 平均层次高度