我试图使用正则表达式来使用php解析变化的字符串,例如,该字符串可以是;

"twoX // threeY"

要么
"twoX /// threeY"

因此,有一个左键关键字,一个由2或3个斜杠组成的divider和一个右键关键字。这些也是我要单独消费的部分。
"/((?<left>.+)?)(?=(?<divider>[\/]{2,3}))([\/]{2,3})((?<right>.+)?)/";

当我在第一个字符串上使用此正则表达式时,所有内容都会正确解析,因此;

左:twoX
分隔线://
右:ThreeY

但是当我在第二个字符串上运行此表达式时,左侧和分隔线无法正确解析。我得到的结果是:

左:twoX /
分隔线://
右:ThreeY

我确实在正则表达式中使用{2,3}为分隔符选择2或3个斜杠。但这似乎不适用于所有匹配字符。
有没有办法让正则表达式解析2或3个斜杠而不复制整个序列?

最佳答案

(.+)?是贪婪的点匹配模式,它匹配尽可能多的字符,最小为1。因此,由于下一个模式仅需要2个字符,因此只有2个字符将被捕获到下一个组中,第一个/将属于组1。

在第一组中使用惰性模式:

'~(?<left>.*?)(?<divider>/{2,3})(?<right>.*)~'
          ^^^


请参见regex demo。如果需要,在模式周围添加^$锚点以匹配整个字符串。

请注意,您无需在前行和消耗模式部分中重复相同的模式,它只会使模式变得笨重,(?=(?<divider>[\/]{2,3}))([\/]{2,3}) = (?<divider>[\/]{2,3})

细节


(?<left>.*?)-组“ left”,它与除换行符以外的任何0+个字符匹配的尽可能少
(?<divider>/{2,3})-2或3个斜杠(由于~用作正则表达式分隔符,因此无需转义)
(?<right>.*)-组“正确”匹配尽可能多的除换行符以外的任何0+字符(直到行尾)。


还有更自然的拆分方法,请参见PHP demo

$s = "twoX // threeY";
print_r(preg_split('~\s*(/{2,3})\s*~', $s, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY));
// => Array ( [0] => twoX [1] => // [2] => threeY )


您会丢失名称,但可以在以后的步骤中添加它们。

10-06 05:28