我有很长的正则表达式,里面有两个复杂的子模式。我如何以任何顺序匹配该子模式?
简化示例:
/(apple)?\s?(banana)?\s?(orange)?\s?(kiwi)?/
我想匹配两个
apple banana orange kiwi
apple orange banana kiwi
这是非常简化的示例。就我而言banana
,orange
是长期复杂的子模式,我不想做类似的事情
/(apple)?\s?((banana)?\s?(orange)?|(orange)?\s?(banana)?)\s?(kiwi)?/
是否可以在字符类中对像chars这样的子模式进行分组?
要求的UPD实数据:
14:24 26,37 Mb
108.53 01:19:02 06.07
24.39 19:39
46:00
我的琴弦长了很多,但这很重要。在这里您可以看到两行我需要匹配的内容。第一个具有两个值:length
(14分24秒)和size
26.37 Mb。第二个具有三个值,但顺序不同:size
108.53 Mb,length
01 h 19 m 02 s和date
June,07第三个具有两个值,size
而length
第四个只有两个,length
还有更多变化,我需要解析所有值。
我有一个非常接近的正则表达式,除了我不弄清楚如何不按两次就写出不同的顺序来匹配模式。
(?<size>\d{1,3}\[.,]\d{1,2}\s+(?:Mb)?)?\s?
(?<length>(?:(?:01:)?\d{1,2}:\d{2}))?\s*
(?<date>\d{2}\.\d{2}))?
注意:这只是大型regexp的一部分,已经可以正常使用了。
编辑的另一种方式:
我假设一行不能包含多个日期,长度或大小,并且我使用一个简单的替代方法:
$subject = <<<'LOD'
14:24 26,37 Mb
108.53 01:19:02 06.07
24.39 19:39
46:00
LOD;
$pattern = <<<'LOD'
~
^
(?>
(?> (?<date> (?> 0[0-9] | 1[012] ) \. (?> [0-2][0-9] | 3[01] )(?! \h+ Mb) )
| (?<length> (?> (?>01:)? [0-9]{1,2} : [0-9]{2} ) )
| (?<size> [1-9][0-9]{0,2} [.,] [0-9]?[1-9] (?> \h+ Mb)? )
)
(?> \h | $ )
){1,3} $
~xm
LOD;
preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);
print_r($matches);
\h
:水平白色字符(空格或制表符)
条件方式:
您可以使用条件(?(condition)true|false)
:
(banana)? orange (?(-1)|\g<-1>)
-1
捕获组的相对位置(即最后一个)在哪里,并\g<-1>
指向此捕获组。
您可以通过以下方式转换此条件模式:如果左侧的第一个捕获组捕获了某些内容,则不执行其他任何匹配捕获组的操作
PHP中的示例文本示例:
$subject = <<<'LOD'
apple banana orange kiwi
apple orange banana kiwi
LOD;
$pattern = '~(apple)?\s?(banana)?\s?(orange)?\s?(?(-2)|\g<-2>)\s?(kiwi)?~';
preg_match_all($pattern, $subject, $matches);
print_r($matches);
注意:
您可以使用oniguruma语法轻松地重用子模式\g<...>
:
\g<2> # second capturing group of the pattern
\g<-2> # second capturing group on the left from the current position
\g<+2> # the same on the right
\g<size> # refer to the subpattern of the named capture (?<size>...)
如果需要,可以使用定义部分来构建模式,例如:
$pattern = <<<'LOD'
~
# definitions
(?(DEFINE)
(?<b> banana )
(?<o> orange )
(?<fruit> \g<b> | \g<o> | kiwi | apple )
)
# pattern
\g<b> \s \g<o> | \g<o> \s \g<b>
~x
LOD;
使用这种工具,可以避免重复子模式的内容。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句