以任何顺序匹配子模式

雅罗斯拉夫

我有很长的正则表达式,里面有两个复杂的子模式。我如何以任何顺序匹配该子模式?

简化示例:

/(apple)?\s?(banana)?\s?(orange)?\s?(kiwi)?/

我想匹配两个

apple banana orange kiwi
apple orange banana kiwi

这是非常简化的示例。就我而言bananaorange是长期复杂的子模式,我不想做类似的事情

/(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秒)和size26.37 Mb。第二个具有三个值,但顺序不同:size108.53 Mb,length01 h 19 m 02 s和dateJune,07第三个具有两个值,sizelength第四个只有两个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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

以任何顺序匹配子模式

来自分类Dev

忽略c ++ 11中的子模式匹配表示法

来自分类Dev

Bootstrap 3子模式?

来自分类Dev

如何递归子模式?

来自分类Dev

正则表达式-匹配模式,但返回子模式

来自分类Dev

JSON模式:引用本地子模式

来自分类Dev

是否可以在正则表达式中命名子模式,然后按C ++中的子模式名称提取匹配项?

来自分类Dev

PHP:试图了解子模式正则表达式匹配

来自分类Dev

正则表达式匹配重复的子模式

来自分类Dev

如何匹配C#中的第一个子模式?

来自分类Dev

猫鼬子模式数组虚拟

来自分类Dev

Mongodb 原子模式规划

来自分类Dev

具有命名子模式的正则表达式看不到最佳匹配

来自分类Dev

如何从不同的捕获组中的可选子模式匹配中分离出连续的十进制值?

来自分类Dev

awk 匹配关键字并检查另一个字段的子模式

来自分类Dev

子模式关闭后,Bootstrap模式不会滚动

来自分类Dev

如何查找不包含子模式的模式?

来自分类Dev

使离子模式以横向模式打开应用

来自分类Dev

从第n个子模式中排除元素

来自分类Dev

离子模式:清除点击/取消的所有字段

来自分类Dev

正则表达式,获取子模式

来自分类Dev

从离子模式调用函数后参数混乱

来自分类Dev

RegExp子模式可用于不同的开闭条件?

来自分类Dev

如何从代码中获取当前的离子模式

来自分类Dev

meteor.js&collection2-如何查询子模式

来自分类Dev

猫鼬-子模式引用父子文档

来自分类Dev

字符串子模式识别优化

来自分类Dev

Akka.net:集群中每个实体的子模式

来自分类Dev

如何使离子模式“解散”方法起作用