ascetik/regex

正则表达式处理

v0.2.0 2024-01-28 14:20 UTC

This package is auto-updated.

Last update: 2024-01-28 14:21:39 UTC


README

use Ascetik\Regex\Core\Regex;

正则表达式

面向对象处理正则表达式的方法

发行说明

v0.2.0 : 匹配带偏移捕获

主要改进是可以使用 PREG_OFFSET_CAPTURE 标志进行匹配。使用此标志与 Regex 实例相结合,可以使用匹配字符串序列中发生的位置的偏移。

一些更改是内部优化。

选项和部分/全局模式处理与之前版本相同。

微小破坏性更改:MatchOperator::apply() 方法被 capture() 方法取代。

该软件包目前仅提供 preg_match* 功能。替换功能尚不可用。

基本用法

第一个示例:检查字符串是否与正则表达式模式匹配

$valid = Regex::from('/([a-b]+)/')->match('test')->capture()->isValid();

var_dump($valid): // true.

无效匹配将返回 false。

测试主题的匹配部分是可用的

$occurences = Regex::from('/([a-b]+)/')->match('test')->capture()->occurences();

var_dump($occurences->content()): // StringMatchSet<StringOccurence['test']>
var_dump($occurences->flatContent()): // [ 0 = 'test']

无效匹配在两种情况下都会返回空数组

使用 php 的 preg_match()preg_match_all(),'$matches' 的第一个元素包含与完整正则表达式模式匹配的文本。这在本软件包中称为“报告”,可以通过这种方式获得

$report = Regex::from('/([a-b]+)/')->match('test')->capture()->report();

echo $report->content(): // 'test'

无效匹配将返回表示失败原因的消息:对于不匹配的字符串,返回“unmatch”,如果发生错误,返回 preg_last_error_msg()

以下是此过程的常规分解

$regex = Regex::from('/([a-b]+)/'); // This factory method parses the input string to get delimiter, main pattern and options

$operator = $regex->match('test'): // this is a MatchOperator, providing new options to configure the match-check result format.

$capture = $operator->capture(); // this is a BasicCapture, from Capture interface family

$valid = $capture->isValid(); // simple boolean

$report = $capture->report(); // this is a StringReport, from MatchReport family
echo $capture->content(); // simple string from this kind of Capture instance

$occurences = $capture->occurences(); // StringOccurenceSet instance, from OccurencesContainer interface family
$container = $occurences->content(); // StringOcurrence[]
$flatContainer = $occurences->flatContent(); // string[]

// $occurences instance would be empty on invalid result.

$occurence = $container[0]; // StringOccurence instance, none if invalid or no matches

这些示例使用默认的 'null' preg_match 标志。然而,这些输出中的一些可能略有不同,具体取决于使用的标志。所有 Capture 实现都具有基本行为。其中一些可能具有特定行为。

模式解析

Regex 实例初始化时进行了一些控制。选项和分隔符都从给定的模式中解析出来,以转换为实例。

以静默方式应用了一些限制,忽略错误值或将它们替换。

使用选项

将插入的模式解析以获取分隔符、主要模式和可能具有的选项。php.net 文档中报告的所有选项都可用。

可用选项在枚举中描述。任何未知选项(对于 global 之外的 'g' 除外)将被忽略。

'g' 选项单独处理,并将 Regex 实例设置为“全局”。

// to build a global multiline case-insensitive regex :
$optionRegex = Regex::from('/([a-b]+)\-?/gmi');
$optionRegex->isGlobal(); // true
echo $optionRegex->pattern()->expression(); // '/([a-b]+)\-?/gim'

// to turn a global Regex to a partial one
$partialRegex = $globalRegex->partial();
$partialRegex->isGlobal(); // false
echo $optionRegex->pattern()->expression(); // '/([a-b]+)\-?/im'

// and inverse
$globalRegex = $regex->global();
echo $optionRegex->pattern()->expression(); // '/([a-b]+)\-?/gim'

分隔符

分隔符在枚举中描述。当解析模式时,分隔符必须匹配并作为 Delimiter 枚举案例列出。

进行了一些检查

  • 如果任何分隔符未列出或缺失,则使用正斜杠作为默认分隔符。
  • 如果起始和结束的分隔符不同,则它们都将被替换为可能的默认分隔符。

然而,任何使用此软件包的用户都应使用与 php 基本正则表达式函数兼容的模式。

高级匹配功能

之前示例使用默认的“null-like”标志。这个版本提供了一个新功能,可以在匹配测试中使用第一个标志。

匹配范围

匹配测试可能涉及字符串的第一个匹配元素或所有匹配元素。对于 Regex 实例,默认范围是部分匹配。

对于全局匹配测试

$globalRegex = $regex->global();

这个特性将在下一个版本中更改,破坏一些使用此方法的部分。现在,它将保持不变,直到我实现所有基本功能。(无论如何,我们都不在乎,只有我一个人想用这个玩意...)

带有偏移量的匹配

MatchOperator 实例提供了一种使用 preg_match* 的 '$offset' 参数的方法

$operator = Regex::from('/([a-b]+)/')
   ->match('test');
echo $operator->atIndex(2)->capture()->content(); // prints 'st'

atIndex() 方法返回一个 MatchOperator 的新实例。

MatchOperator::toIndex() 方法可以与任何类型的 Capture 一起使用。

使用 PREG_OFFSET_CAPTURE 标志

'flag' 是 preg_match()/preg_match_all() 函数的第四个可选参数。

这个版本提供了使用 PREG_OFFSET_CAPTURE 标志的能力,以便检索匹配块及其在主题源字符串中的位置。

PREG_OFFSET_CAPTURE 标志的使用返回一个具有巨大差异的结果。第一个差异是“报告”可能包含多个匹配项。第二个差异是匹配项不仅是字符串,还是一个包含字符串和整数的数组。

为了使现有的正则表达式系统适应这种类型的输出,这个包提供了满足这些需求所需的所有功能。

以下是一个示例

$occurences = Regex::from('/([a-b]+)/')
   ->match('test')
   ->offsetCapture() // now we call offsetCapture() instead of capture()
   ->occurences();

var_dump($occurences->content()): // IndexedMatchSet<IndexedOccurence['test', 0]>
var_dump($occurences->flatContent()): // [ 0 = 'test']

以下是其分解

$regex = Regex::from('/([a-b]+)/'); // This factory method parses the input string to get delimiter, main pattern and options

$operator = $regex->match('test'): // this is a MatchOperator, providing new options to configure the match-check result format.

$capture = $operator->offSetapture(); // this is an IndexedCapture, from Capture interface family

$valid = $capture->isValid(); // still a simple boolean

$report = $capture->report(); // this is either an IndexedReport for a succesful check on a StringReport in case of failure.
echo $capture->content(); // IndexedOccurenceSet if valid, string otherwise

$occurences = $capture->occurences(); // IndexedOccurenceSet instance, from OccurencesContainer interface family
$container = $occurences->content(); // IndexedOcurrence[]
$flatContainer = $occurences->flatContent(); // string[]

$occurenceExample = $container[0]; // IndexedOccurence instance, none if invalid
echo $occurenceExample->content(); // 'test', for our example
echo $occurenceExample->index(); // 0 in our example, matching string position in the input subject.

如您所见,有一些细微的差异。主要机制始终相同,使用与匹配模式和使用的标志相关的不同策略。

后续功能

  1. 更多标志!!即将推出:UnmatchedAsNull。

  2. 请参阅下方的“问题”。

  3. 正则表达式替换:使用正则表达式处理替换有三种方法,有时使用不同类型的参数。我只需要调整现有实现使其工作。

  4. 也许是一个逐步的正则表达式模式构建器...

  5. 以及一些我显然忘记的其他事情!

问题

这个版本只是一个草案。开发是逐步进行的,保持次要版本号在1.0以下。

当前 MatchOperator 的实现没有区分 preg_match 和 preg_match_all 的结果。根据PHP文档,第二个函数允许更多的标志。在这种情况下,使用一个特定的 MatchOperator 实现并使用适应每个可用标志的方法会更好。

在实现 PREG_UNMATCHED_AS_NULL 标志的下一个版本中,将包含有关部分/全局模式的一些破坏性更改,以提供不同的操作符实现。