我试图使用正则表达式来使用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 )
您会丢失名称,但可以在以后的步骤中添加它们。