jackjohansson / oopcre
基于OOP的PHP正则表达式
Requires
- php: 8.1
- ext-mbstring: *
- ext-pcre: 2.*
This package is auto-updated.
Last update: 2024-09-15 15:43:20 UTC
README
目录
- OOPCRE是什么,为什么我应该关心它?
- 安装与需求
- 结构与用法
- 开始正则表达式操作
Preg*
类集
- 基本示例
- 高级用法
- 深入了解结构
- 正则表达式类
- 配置器类
- 错误处理器类
- 模式类
- 量词构建器类
- 模式构建器类
- 修饰符构建器类
- 分组和命名模式
- 注册模式数组
- 预定义项
- 辅助特性
1) OOPCRE是什么,为什么我应该关心它?
OOPCRE(发音为 o-o-pi-si-ar-E
,或者我最喜欢的 oopsie! R-E
)是一个提供面向对象正则表达式操作方法的包。你为什么需要它?实际上,你可能不需要。但就像许多用于简化开发工作的包一样,你可以使用OOPCRE来实现相同的功能。如果你是以下情况,它将是一个很好的选择:
- 你不是正则表达式大师,也没有时间成为一位
- 你希望快速将可读代码转换为正则表达式模式
- 你希望使用OOPCRE提供的众多辅助方法
- 你希望使用你可能甚至不知道存在的正则表达式功能
无论你是使用简单操作来检测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 )
将添加一个字符范围匹配模式。例如,从 h
到 t
(传递为 [ 'h' => 't' ]
)或从 3
到 8
(传递为 [ 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()
方法接受一个自定义的组名作为其第二个参数,但除非你启用了重复的组名,否则你应该避免这样做。即使如此,也不推荐这样做。
分组模式还允许你快速找到它。两个匹配类(PregMatch
和 PregMatchAll
)都提供了一个 ->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
包含不可打印的字符列表,如换行符和回车符。你可以在构建正则表达式时使用这些情况。Whitespace
与Unprintable
类似,但它只包含空白字符。
7) 辅助工具
OOPCRE 提供了一组特质,你可以在项目中使用它们来快速解决常见的正则表达式问题。这些特质不使用 OOPCRE 内部,也不需要 PHP 8.1,它们主要添加是为了方便并覆盖常见情况。它们位于 /src/Helper/Common
目录下,并在 \OOPCRE\Helper\Common
命名空间中注册。以下列出了这些特质的列表,你可以查看它们以了解它们提供了什么。享受!
UserInput
提供了解析和验证常见用户输入的方法。Html
提供了在 HTML 内容上执行常见操作的方法。Datetime
提供了一组验证和解析常见日期和时间的方法。Http
有验证和操作 HTTP uri 和结构的方法。File
提供了验证常见文件系统元素的方法。