基于OOP的PHP正则表达式

安装: 0

依赖项: 0

建议者: 0

安全: 0

星标: 0

关注者: 1

分支: 0

开放性问题: 0

类型:项目

dev-master 2022-07-16 10:39 UTC

This package is auto-updated.

Last update: 2024-09-15 15:43:20 UTC


README

目录

  1. OOPCRE是什么,为什么我应该关心它?
  2. 安装与需求
  3. 结构与用法
    1. 开始正则表达式操作
    2. Preg*类集
  4. 基本示例
  5. 高级用法
  6. 深入了解结构
    1. 正则表达式类
    2. 配置器类
    3. 错误处理器类
    4. 模式类
    5. 量词构建器类
    6. 模式构建器类
    7. 修饰符构建器类
    8. 分组和命名模式
    9. 注册模式数组
    10. 预定义项
  7. 辅助特性

1) OOPCRE是什么,为什么我应该关心它?

OOPCRE(发音为 o-o-pi-si-ar-E,或者我最喜欢的 oopsie! R-E)是一个提供面向对象正则表达式操作方法的包。你为什么需要它?实际上,你可能不需要。但就像许多用于简化开发工作的包一样,你可以使用OOPCRE来实现相同的功能。如果你是以下情况,它将是一个很好的选择:

  1. 你不是正则表达式大师,也没有时间成为一位
  2. 你希望快速将可读代码转换为正则表达式模式
  3. 你希望使用OOPCRE提供的众多辅助方法
  4. 你希望使用你可能甚至不知道存在的正则表达式功能

无论你是使用简单操作来检测HTML字符串中的图像标签,还是尝试运行复杂的正则表达式操作,OOPCRE都会在你身边提供帮助。由于它没有依赖项,且仅在运行一次时执行preg_*函数,因此它非常轻量级。

2) 安装与需求

要安装此包,只需运行以下composer命令

composer require jackjohansson/oopcre

你也可以下载此包并解压缩zip文件,然后运行以下命令,因为此包没有依赖项

composer dump-autoload

OOPCRE除了PHP版本外没有特殊要求。它依赖于PHP 8.1版本发布的新功能,如枚举和只读属性,因此它需要至少PHP 8.1.0才能运行。第7节中包含的辅助特性没有要求。

3) 结构与用法

以下我们将解释如何开始使用任何正则表达式操作,列出所有提供的方法,并对它们进行简要说明。

3.1) 开始正则表达式操作

要使用OOPCRE进行任何操作,需要创建一个\OOPCRE\Regex类的新实例。此类需要将正则表达式主题传递给其构造函数

/**
 * Initialize the regex operation on a given subject.
 * A subject can be any of these types:
 * 
 * 1) String
 * 2) String[] ( An array with strings/stringables as values )
 * 5) Integer
 * 6) Float
 * 7) Objects that have a _toString() method
 *
 * Passing a null value will short-circuit the operation
 * and throw an exception, or return false.
 *
 */
$regex = new \OOPCRE\Regex( $subject );

在开始任何操作之前,我们可以设置配置。我们可以在执行之前任何时候设置这些配置,但最好是将其放在顶部以避免混淆。要设置配置,可以在新创建的\OOPCRE\Regex类上调用setConfig()方法。此方法接受一个\OOPCRE\Foundation\Definition\Option枚举实例作为其第一个参数,以及一个值作为其第二个参数。例如,要设置分隔符,运行

$regex->setConfig( \OOPCRE\Foundation\Definition\Option::DELIMITER, '/' );

此用法中最常见的情况是在错误发生时启用异常,这会在发生关键错误时抛出\OOPCRE\Foundation\Exception\RegexException实例

$regex->setConfig( \OOPCRE\Foundation\Definition\Option::ENABLE_EXCEPTIONS, TRUE );

3.2) Preg*类集

现在我们已经实例化了主题,可以使用 Preg* 中的一个类来开始执行正则表达式操作。您可以通过在正则表达式主题上调用以下方法之一来访问这些类:

1) $regex->match();

返回一个 \OOPCRE\Foundation\PCRE\PregMatch 类的实例,类似于 preg_match()。此类允许您快速将单个字符串与单个模式匹配,并检查是否匹配。

2) $regex->matchAll();

返回一个 \OOPCRE\Foundation\PCRE\PregMatchAll 类的实例,与 preg_match_all() 函数和 ->match() 方法类似。不同之处在于它还支持捕获组、计数结果和不在第一次匹配时停止。

3) $regex->replace();

返回一个 \OOPCRE\Foundation\PCRE\PregReplace 类的实例,类似于 preg_replace() 函数。此类允许您用一个给定的字符串替换单个模式,默认设置为空字符串。您可以通过在这个类上调用 ->replacement() 方法来设置替换字符串。

4) $regex->replaceMulti();

返回一个 \OOPCRE\Foundation\PCRE\PregReplaceMultiple 类的实例,允许您在多个主题上使用多个字符串替换多个模式。主题可以是字符串或具有可字符串化值(例如具有 _toString() 方法的对象)的数组。有关如何注册多个模式的说明,请参阅 6.9。

5) $regex->filter();

返回一个 \OOPCRE\Foundation\PCRE\PregFilter 类的实例,与 preg_filter() 类似,而 preg_filter() 本身又类似于 preg_replace()。您可以使用此方法替换和过滤与单个模式匹配的数组主题。

6) $regex->filterMulti();

返回一个 \OOPCRE\Foundation\PCRE\PregFilterMultiple 类的实例,与先前方法类似,但允许注册多个模式。

7) $regex->grep();

返回一个 \OOPCRE\Foundation\PCRE\PregGrep 类的实例,类似于 preg_grep() 函数。它将过滤并返回与给定模式匹配(或如果不匹配则启用)的数组主题中的项目。

8) $regex->split();

返回一个 \OOPCRE\Foundation\PCRE\PregSplit 类的实例,类似于 preg_split()。它允许您根据给定的模式将给定的主题分割成字符串数组。如果您的模式非常简单,请考虑使用 PHP 的 explode() 函数。

这些类都实现了 \OOPCRE\Foundation\Skeleton\PcreSkeleton 接口,并扩展了 \OOPCRE\Foundation\PCRE\PregBase 抽象类。代码有很好的文档,因此任何适当的 IDE 都将提供完整的自动完成。现在让我们尝试进行基本的正则表达式操作来查找一些文本。

4) 基本示例

我们将尝试使用 match() 方法以及 \OOPCRE\Foundation\Pattern\PatternBuilder 类来查看主题是否包含字母数字文本。此类提供了一种简单且方便的方法来构建正则表达式,而无需了解有关正则表达式模式的知识。

我们通过调用 patterns() 方法开始构建模式。

$patternBuilder = $match->patterns();
$patternBuilder->simpleRange( [ 'a' => 'f', '0' => '9' ] );

上述代码将被编译为 [a-zA-Z0-9]。您可以通过在 PatternBuilder 实例上调用 getPatternString() 手动构建和检查完整模式,这将返回模式字符串。在您完成构建模式后,您可以在 match() 方法的 execute() 方法上调用它(返回 \OOPCRE\Foundation\PCRE\PregMatch 类的实例)以执行操作并获得结果。此方法返回一个布尔值,它将告诉您是否进行了匹配、替换或过滤。

if( $match->success() ) {
    // String matched! Do some stuff.
}

其他操作,如 matchAll()filter(),根据情况提供额外的 count()results() 等方法。例如,在 \OOPCRE\Foundation\PCRE\PregMatchAll(由 matchAll() 方法返回)上调用 count() 方法将返回匹配的数量。

5) 高级用法

既然我们已经匹配了一些基本的字符串并享受了一些乐趣,让我们尝试一个真实的例子。我们将尝试在 HTML 代码中匹配一个图像标签。让我们首先设置一些修饰符。我们将告诉程序不要在新行上停止,并忽略大小写。

$match->modifiers()->caseInsensitive()->multiline();

《modifiers()`方法返回一个\OOPCRE\Foundation\Pattern\ModifierBuilder类的实例,其行为类似于PatternBuilder类。这意味着您可以按需多次链接修饰符。现在让我们构建模式。

这次,我们将调用add*()方法。这些方法返回一个\OOPCRE\Foundation\Pattern\Pattern类的实例,并允许更多的灵活性和配置。

$patterns = $match->patterns();
// Match an opening `<img` tag.
$patterns->addText( '<img' );
// Match anything except the `>` character, and keep matching as much as possible.
$patterns->addCharacterClass( '>', TRUE )->unlimited();
// Match a closing `>` HTML tag.
$patterns->addCharacter( '>' );

通过调用$patterns->getPatternString(),您会注意到编译后的模式如下,这是一个匹配任何图像的基本模式。

~<img[^>]*>~im

现在我们可以像之前一样运行execute()方法并检查结果。

请注意,应用程序默认的分隔符设置为~,但可以更改。此外,默认情况下,应用程序不会尝试转义模式,但也可以启用此功能。

6) 深入结构分析

让我们深入分析应用程序的结构,并将其分解为更小的部分,以确切了解正在发生的事情。我们将从应用程序中最小且最重要的部分开始,即\OOPCRE\Regex类。

6.1) Regex类

如前所述,要开始任何正则表达式操作,我们需要实例化\OOPCRE\Regex类并将其主题传递给它。此类提供了以下方法:

// Configurations
->configs();
->setConfig( $name, $value );
->getConfig( $name );

// Modifier override
->globalModifiers();

// Error handling
->errors();
->errorBag();
->lastErrorMessage();
->lastError();

// Regex operations
->match();
->matchAll();
->replace();
->replaceMulti();
->filter();
->filterMulti();
->grep();
->split();

6.2) 配置器类

我们将首先查看配置器。调用前两个配置方法将返回一个\OOPCRE\Foundation\Configurator类的实例,该类也支持在setConfig()方法上链式调用方法。`setConfig()`和`getConfig()`方法都接受一个\OOPCRE\Foundation\Definition\Option枚举实例作为第一个参数,这是我们想要与之一起工作的所需选项。`setConfig()`方法还接受第二个参数,即要设置的给定选项的值。要查看所有可能选项及其默认值,请查看Option枚举。

6.3) 错误处理类

默认情况下,应用程序禁用异常。这意味着错误将被静默忽略,应用程序在遇到致命错误后不会停止。然而,这意味着结果不可靠。如果未启用异常,所有错误都将记录到一个集合中,由\OOPCRE\Foundation\Bag\ErrorBag类处理。此类实现了\OOPCRE\Foundation\Bag\TraversableBag接口,这意味着您可以像数组一样迭代它。要获取此类的实例,请调用Regex类上的errorBag()方法。其他方法的功能如下所述:

  • errorBag()返回ErrorBag类的唯一实例。
  • errors()方法将在ErrorBag类上调用items()方法,该方法返回一个已发生并记录的错误数组。
  • lastError()将返回已静默记录的最后一个异常。如果没有抛出异常,则返回null
  • lastErrorMessage()方法将尝试返回最后发生错误的文本消息。如果没有记录错误,则返回空字符串。

6.4) 模式类

以任何方式注册的每个模式都将存储为基础抽象的\OOPCRE\Foundation\Pattern\Pattern类的实例,该类由其他特定类型的模式在内部扩展。您可以将其视为模式的最小构建块。例如,单个字符、数字或字符范围。

每个特定模式都包含一个静态的create()方法,它接受输入。输入根据每个模式而变化,因此没有类型提示。然而,它将被验证,如果它不满足最低要求,则会引发异常或记录。

create()方法不应直接使用,而应由我们稍后讨论的PatternBuilder类内部使用。

6.5) 量词构建器类

Pattern 类使用了 \OOPCRE\Foundation\Contract\ManagesQuantifier 特性,这允许在模式上应用多个量词。

->atLeast( $min );
->asMost( $max );
->between( $min, $max );
->exactly( $count );
->unlimited();

->greedy();
->possessive();
->reluctant();

上述特性管理着 \OOPCRE\Foundation\Pattern\QuantifierBuilder 类,这意味着您不需要直接与构建器交互。您可以使用上述方法来构建所需的量词。像往常一样,您可以多次链式调用这些方法。以下是每个方法功能的简要说明:

  • ->atleast( $n ) 方法接受一个整数作为输入,并尝试至少匹配给定模式 $n 次。类似于 {n,}
  • ->atMost( $n ) 方法接受一个整数作为输入,并尝试不超过 $n 次匹配给定模式。如果您传递 0 或 -1 给它,它会尽可能多地匹配。如果您提供的数字小于 atLeast(),它将被设置为 atLeast()。类似于 {x,y}。默认为 0。
  • ->between( $x, $y ) 是同时调用 ->atleast()->atMost() 的快捷方法。关于上述方法的规则也适用于此方法。类似于 {x,y}
  • ->exactly( $n ) 方法将尝试精确匹配模式 恰好 $n 次数。它是调用 ->between( $n, $n ) 的快捷方式。类似于 {n}
  • ->greed() 方法将量词设置为贪婪(高级)。
  • ->possessive() 方法将量词设置为占有(高级)。
  • ->reluctant() 方法将量词设置为犹豫(高级)。

要了解更多关于最后 3 个方法的信息,请查看 StackOverflow 上的这个问题:链接

6.6) 模式构建器类

我们上面讨论了 Pattern 类及其工作原理。但如果我们不直接实例化 Pattern 类,我们该如何添加这些模式呢?这就是 \OOPCRE\Foundation\Pattern\PatternBuilder 类发挥作用的地方。该类提供了 3 组广泛的辅助方法,可以注册最复杂的模式。这三组方法的前缀如下:

6.6.1) ->add*() 方法集

这些方法以 add 关键字为前缀,并返回一个 Pattern 类的实例。这允许我们进一步自定义模式,例如设置量词。完整的 add*() 方法集描述如下:

1) ->addAnything()

此方法将匹配任何字符。

2) ->addCharacter( string $char )

此方法将单个字符添加到模式中。

3) ->addCharacterClass( string $characters, bool $not )

此方法将字符类匹配添加到模式中。

4) ->addFloat( float $float, int $precision, bool $unsigned )

将添加一个模式以匹配浮点数。将 true 传递给第二个参数将添加浮点数的绝对值。

5) ->addInteger( int $int, bool $unsigned )

将添加一个模式以匹配整数。将 true 传递给第二个参数将添加整数的绝对值。

6) ->addMetaChar( Metacharacter $metacharacter )

接受一个 \OOPCRE\Foundation\Definition\Metacharacter 枚举的实例,并将添加一个模式以匹配预定义的元字符。您可以在 Metacharacter 枚举中查看完整选项列表。

7) ->addRange( array $range, bool $not )

将添加一个字符范围匹配模式。例如,从 ht(传递为 [ 'h' => 't' ])或从 38(传递为 [ 3 => 8 ])。将 true 传递给第二个参数将反转匹配。将执行一些验证以确保范围有意义。

8) ->addText( string $text )

将添加一个模式以匹配文本字符串,例如单词。

9) ->addUnicode( string $code )

将匹配一个 Unicode 字符。您应仅传递没有 \u 前缀的 Unicode。例如,3a2d1F

10) ->addUnprintable( Unprintable $unprintable )

接受一个\OOPCRE\Foundation\Definition\Unprintable枚举实例,并匹配无法打印的字符,例如换行符。

11) ->addWhitespace( Whitespace $whitespace )

接受一个\OOPCRE\Foundation\Definition\Whitespace枚举实例,并将匹配空白字符。默认为一个空格。

6.6.2) ->simple*()方法集

这些方法用于向模式构建器添加一个非常基本的项。它们不返回创建的Pattern类实例,而是返回正在使用的同一PatternBuilder实例。请注意,我们提到了当前,因为一些操作(如替换)可以有模式数组,因此有模式构建器数组。以下为这些方法的完整列表。然而,由于它们的行为类似于add*()方法,所以省略了描述。

1)  ->simpleCharacter( string $char )
2)  ->simpleCharacterClass( string $characters, bool $not )
3)  ->simpleFloat( float $float, int $precision, bool $unsigned )
4)  ->simpleInteger( int $int, bool $unsigned )
5)  ->simpleMetaChar( Metacharacter $metacharacter )
6)  ->simpleRange( array $range, bool $not )
7)  ->simpleText( string $text )
8)  ->simpleUnicode( string $code )
9)  ->simpleUnprintable( Unprintable $unprintable )
10) ->simpleWhitespace( Whitespace $whitespace )

6.6.3) ->posix*()方法集(高级)

->posix*()方法将预定义的POSIX字符类添加到模式中。这些方法如下

1) ->posixAlpha()

匹配字母字符。类似于[[:upper:][:lower:]]

2) ->posixAlphaNumeric()

匹配字母和数字字符。类似于[[:alpha:][:digit:]]

3) ->posixBlank()

匹配空格或制表符字符。类似于[ \t]

4) ->posixCtrlChar()

匹配控制字符。

5) ->posixDigit()

匹配任何数字。类似于[0-9]

6) ->posixGraph()

匹配非空白字符(不包括空格、控制字符等)。类似于[^ \t\n\r\f\v]

7) ->posixLowerCase()

匹配小写字母字符。类似于[a-z]

8) ->posixPrint()

类似于[:graph:],但包括空格字符。类似于[^\t\n\r\f\v]

9) ->posixPunctuation()

匹配标点符号字符。类似于[.,!?:…]

10) ->posixSpace()

匹配空白字符(包括空格、换行、回车等)。类似于[ \t]

11) ->posixUppercase()

匹配大写字母字符。类似于[A-Z]

12) ->posixHexDigit()

匹配十六进制数字中的数字(即0-9a-fA-F)。类似于[0-9A-Fa-f]

6.6.4) 其他方法

除了上述三组方法之外,PatternBuilder类还提供了另外4个方法

  • ->group( \Closure $closure, string $name )。此方法允许您定义一个命名的模式组。传递给其第一个参数的闭包将接收到一个新的PatternBuilder实例,这允许您构建一个新的完整的子模式并将其命名。省略name参数将为该组生成一个随机名称。
  • ->getPatternString()方法返回编译后的模式。
  • ->modifiers()方法返回一个修饰符构建器实例。将在稍后解释。
  • ->raw( string $text )方法允许您将原始且未转义的字符串添加到模式中,例如[a]{2}(foo|bar)。输入将不会进行处理,因此请谨慎使用。

6.7) 修饰符构建器类

PatternBuilder类上调用->modifiers()方法将返回当前用于当前模式的\OOPCRE\Foundation\Pattern\ModifierBuilder类实例。如果没有将修饰符添加到模式中,则返回新的ModifierBuilder类实例。

此类提供了以下方法,每个方法都添加了OOPCRE\Foundation\Definition\Modifier支持的枚举的一个情况。每个修饰符在Modifier枚举类中都有详细的解释,所以我们将跳过描述。

  • ->anchored()
  • ->caseInsensitive()
  • ->dollarEndOnly()
  • ->dotAll()
  • ->extended()
  • ->extra()
  • ->multiline()
  • ->study()
  • ->ungreedy()
  • ->unicode()

同样,每个方法都返回ModifierBuilder的实例,因此您可以连续调用这些方法,只要它们在逻辑上合理。

6.8) 分组与命名模式

如前所述,您可以在PatternBuilder类上调用->group()方法将一组模式分组在一起。这对于使用允许捕获命名子模式的preg_match*方法特别有用。以下是如何分组模式的示例。让我们重复之前的示例

$patterns = $match->patterns();
$patterns->addText( '<img' );
$patterns->addCharacterClass( '>', TRUE )->unlimited();
$patterns->addText( 'src=' );
$patterns->group(
    function ( \OOPCRE\Foundation\Pattern\PatternBuilder $builder ) {
        $builder->addCharacterClass( '\'"', TRUE )->unlimited();  
    }
);
$patterns->addCharacterClass( '>', TRUE )->unlimited();
$patterns->addCharacter( '>' );

上面的模式将被编译成类似以下的内容

~<img[^>]*src=(?P<oopcre_6241ff33eadd0>[^'"]*)[^>]*>~im

请记住,->group() 方法接受一个自定义的组名作为其第二个参数,但除非你启用了重复的组名,否则你应该避免这样做。即使如此,也不推荐这样做。

分组模式还允许你快速找到它。两个匹配类(PregMatchPregMatchAll)都提供了一个 ->results() 方法,该方法返回 \OOPCRE\Foundation\Pattern\Result 类的实例或多个实例,具体取决于情况。Result 类有 3 个只读属性

  • ->name 这个属性持有组的名称。
  • ->content。这个属性持有匹配的字符串。
  • ->offset 持有匹配发生的位置,即字符串的起始偏移量。

6.9) 注册模式数组

某些操作,如 replaceMulti(),支持输入模式的数组。这些操作提供了一个 register() 方法,你可以用它来开始注册一个新的模式构建器。此方法返回一个具有自己的修饰符的模式构建器的新实例。以下是一个示例

$multiple = $regex->replaceMulti();

// Register 1st pattern
$multiple->register( 'replacement' )
->simpleCharacter( 'a' )
->simpleFloat( 2.5 );

// Register 2nd pattern
$multiple->register('example')
->simpleMetaChar( Metacharacter::ANY )
->addText( 'some-string' )
->between( 1, 3 );

// Execute
$result = $multiple->execute()

register() 方法接受一个替换字符串或一个可调用的函数,该函数将在替换即将发生时被调用。可调用的函数由 PHP 的 preg_* 函数调用,并接收与它们提供的相同的参数。

6.10) 预定义项

OOPCRE 提供了一组预定义的枚举,可以在应用程序中使用。这些枚举位于 /src/Foundation/Definition 目录下,并在 OOPCRE\Foundation\Definition 命名空间中注册。以下是这些枚举及其用途的完整列表。

  • Metacharacter 枚举包含称为元字符的特殊正则表达式字符。你可以在使用元字符方法时使用这些情况。
  • Modifier 枚举用于内部构建修饰符。你可以查看它以了解更多关于每个修饰符做什么的信息。
  • Option 枚举包含可能的配置值列表及其默认值。
  • PosixPattern 包含支持的 POSIX 模式的数组,你可以在正则表达式操作中使用它作为缩写。
  • Quantifier 包含前面解释过的正则表达式量词列表。内部使用。
  • ServiceMap 是一个内部枚举,包含默认服务注册和由服务容器提供的列表。
  • Unprintable 包含不可打印的字符列表,如换行符和回车符。你可以在构建正则表达式时使用这些情况。
  • WhitespaceUnprintable 类似,但它只包含空白字符。

7) 辅助工具

OOPCRE 提供了一组特质,你可以在项目中使用它们来快速解决常见的正则表达式问题。这些特质不使用 OOPCRE 内部,也不需要 PHP 8.1,它们主要添加是为了方便并覆盖常见情况。它们位于 /src/Helper/Common 目录下,并在 \OOPCRE\Helper\Common 命名空间中注册。以下列出了这些特质的列表,你可以查看它们以了解它们提供了什么。享受!

  • UserInput 提供了解析和验证常见用户输入的方法。
  • Html 提供了在 HTML 内容上执行常见操作的方法。
  • Datetime 提供了一组验证和解析常见日期和时间的方法。
  • Http 有验证和操作 HTTP uri 和结构的方法。
  • File 提供了验证常见文件系统元素的方法。