可选的非捕获组正则表达式

时间:2017-05-25 22:13:26

标签: php regex regex-greedy regex-group

我在一个简单的模式中苦苦挣扎,我需要最多匹配3个字符串或至少2个字符串

可以是:

banana-split.taste

或者

banana.taste

我想要的是一切之前和之后的一切。 但如果在点之前的字符串中恰好存在连字符,我希望字符串位于连字符和点之间

通过我的例子,结果如下:

示例1

match[1] = banana
match[2] = split
match[3] = taste

示例2

match[1] = banana
match[2] = 
match[3] = taste

我尝试的是使用正面向前/后面但我觉得我使用得很糟糕

(.+)(?<=\-)(.*?)?\.(.+)

有了这个,我能很好地得到第一个例子,但不是第二个

2 个答案:

答案 0 :(得分:2)

使用否定字符类和可选组:

jdk8u131-b11

请参阅regex demo

<强>详情:

  • ([^-]+)(?:-([^.]+))?\.(.+) - 第1组:尽可能多地使用([^-]+)以外的一个或多个字符
  • - - 匹配1或0次出现的可选组:
    • (?:-([^.]+))? - 连字符
    • - - 第2组:尽可能多地使用([^.]+)以外的一个或多个字符
  • . - 一个点
  • \. - 除了换行符之外的任何1个字符

答案 1 :(得分:2)

Wiktor的答案没有错;我非常重视他的答案质量。

纯粹出于教育目的,我想解释preg_match()不是唯一一个从字符串中提取子串的基于正则表达式的函数。考虑这个单线:

方法:

var_export(preg_split('/[-\.]/',$str));

输入/输出:

$str='banana-split.taste';  // ['banana','split','taste']
$str='banana.taste';  // ['banana','taste']

注意preg_split()如何不使用捕获组(因此没有空捕获组)并且在其输出中不包含(通常无用的)全字符串匹配。

我不知道您正在使用的流程,但如果这样可以简化您的流程,那么我很高兴我能够参与其中。