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

Optional non capturing group regex

我正在努力解决一个简单的模式,我需要最多匹配 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

我试过的是用positivelookahead/behind但是感觉用的不好

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

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

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

([^-]+)(?:-([^.]+))?\.(.+)

regex demo

详情:

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

Wiktor的回答没有问题;我非常看重他的回答质量。

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

方法:

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

Inputs/Outputs:

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

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

我不知道您正在使用的过程,但如果这简化了您的过程,那么我很高兴参与进来。