zing-studios/matcher

levenshtein 示例

dev-master 2023-02-27 21:58 UTC

This package is not auto-updated.

Last update: 2024-09-25 03:40:58 UTC


README

此库提供以下功能

  1. 填充项
  2. Matcher - 从字符串数组中获取字符串的最佳匹配

使用方法

mb_levenshtein

核心 levenshtein 函数在每个字符串的每个字节上操作,因此当它遇到多字节字符时将返回令人困惑的结果。

mb_levenshtein 是Levenshtein距离算法的支持多字节字符的实现。此实现将核心C函数移植到PHP中,并添加了多字节字符支持。它具有与核心函数相同的参数。

https://php.ac.cn/manual/en/function.levenshtein.php

https://github.com/php/php-src/blob/php-8.1.10/ext/standard/levenshtein.c

echo levenshtein('notre', 'nitre');
// output: 1

echo levenshtein('notre', 'nôtre');
// output 2

echo mb_levenshtein('notre', 'nôtre');
// output 1

Matcher

匹配器将从数组中选择最佳匹配字符串,并返回一个包含从目标字符串中匹配的字符串和与针相似度的结果对象。请注意,相似度分数没有进行任何归一化,它们的值由所使用的比较算法确定。

use Zing\Matcher\Matcher;
use Zing\Matcher\SimilarityComparer\Levenshtein\LevensteinComparer;

$haystack = [
    'fox',
    'cat',
    'dog',
];

$matcher = new Matcher(
    new LevensteinComparer()
);

$result = $matcher->match('bat', $haystack);

echo $result->getString();
//output: cat

echo $result->getSimilarityResult()->getScore();
//output 1

Comparer

匹配器需要提供一个实现 SimilarityComparerInterface 的对象作为第一个参数。比较器用于将针与目标字符串的每个元素进行比较,以获取相似度结果。比较器还用于比较相似度结果以确定哪个更好。例如,对于Levenshtein,较小的数字更好,但对于SimilarText,较高的百分比更好。

此库包含以下比较器

LevensteinComparer - 使用Levenshtein距离算法。

https://php.ac.cn/manual/en/function.levenshtein.php

SimlilarTextComparer - 使用PHP的 similar_text 函数。

https://php.ac.cn/manual/en/function.similar-text.php

平局解决

默认情况下,如果结果被认为是精确匹配,它将立即返回。当没有精确匹配且多个元素与最佳相似度平局时,才需要平局解决。可以通过启用 ALLOW_EXACT_MATCH_TIES 标志来更改此行为。

默认的平局解决规则是返回目标字符串中出现最早的元素。

$haystack = [
    'cat',
    'fat',
    'rat',
];

$matcher = new Matcher(
    new LevensteinComparer()
);

$result = $matcher->match('bat', $haystack);

echo $result->getString();
//output: cat

平局解决器是一个可调用的类,实现了 TieBreakerInterface。它接收针和一组平局的最佳匹配结果。此库附带其他可用的平局解决器。您可以创建自己的平局解决器,通过实现 TieBreakerInterface 并返回平局解决中的获胜者。

use Zing\Matcher\TieBreaker\LastMatch;
use Zing\Matcher\TieBreaker\ThrowException;

$haystack = [
    'cat',
    'fat',
    'rat',
];

$matcher = new Matcher(
    new LevensteinComparer(),
    [],
    new LastMatch()
);

$result = $matcher->match('bat', $haystack);

echo $result->getString();
//output: rat

$matcher = new Matcher(
    new LevensteinComparer(),
    [],
    new ThrowException()
);
//This will throw a TieException which will include the tied results.
$result = $matcher->match('bat', $haystack);

Matcher 选项

通过添加 StrToLowerPreprocessor 预处理器启用不区分大小写的支持。此选项告诉匹配器在将其传递给比较器之前将针和目标字符串转换为小写。未修改的字符串将传递给平局解决器并返回在结果中。

$haystack = [
    'fox',
    'cat',
    'dog',
];

$matcher = new Matcher(
    new LevensteinComparer(),
    [new StrToLowerPreprocessor()]
);

$result = $matcher->match('CAT', $haystack);

echo $result->getString();
//output: cat

echo $result->getSimilarityResult()->getScore();
//output 0
//0 means it was considered to be an exact match

通过将 MULTIBYTE 标志添加到比较器选项参数中,使用比较器的多字节实现。

$haystack = [
    'notre',
    'nôtre',
];

$matcher = new Matcher(
    new LevensteinComparer(SimilarityComparerInterface::MULTIBYTE)
);

$result = $matcher->match('nôtre', $haystack);

echo $result->getString();
//output: nôtre

echo $result->getSimilarityResult()->getScore();
//output 0

您还可以组合 CASE_INSENSITIVEMULTIBYTE 标志。

$haystack = [
    'notre',
    'nôtre',
];

$matcher = new Matcher(
    new LevensteinComparer(SimilarityComparerInterface::MULTIBYTE),
    [new StrToLowerPreprocessor()]
);


$result = $matcher->match('NÔTRE', $haystack);

echo $result->getString();
//output: nôtre

echo $result->getSimilarityResult()->getScore();
//output 0