Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 可变大小的前瞻性消费_Php_Regex_Regex Lookarounds - Fatal编程技术网

Php 可变大小的前瞻性消费

Php 可变大小的前瞻性消费,php,regex,regex-lookarounds,Php,Regex,Regex Lookarounds,我是一个试图使用正则表达式来解析使用php的可变字符串的人,例如,该字符串可以是 "twoX // threeY" 或 所以有一个左关键字,一个由2或3个斜杠和一个右关键字组成的分隔符。这些也是我想单独消费的部分 "/((?<left>.+)?)(?=(?<divider>[\/]{2,3}))([\/]{2,3})((?<right>.+)?)/"; “/((?+)?)(?=(?[\/]{2,3}))([\/]{2

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

"twoX // threeY"

所以有一个左关键字,一个由2或3个斜杠和一个右关键字组成的分隔符。这些也是我想单独消费的部分

"/((?<left>.+)?)(?=(?<divider>[\/]{2,3}))([\/]{2,3})((?<right>.+)?)/";
“/((?+)?)(?=(?[\/]{2,3}))([\/]{2,3})((?+)?)/”;
当我在第一个字符串上使用这个正则表达式时,所有内容都被正确解析,所以

:两个

分隔符://

:三岁

但是当我在第二个字符串上运行这个表达式时,左边和分隔符没有得到正确的解析。我得到的结果是

:两个/

分隔符://

:三岁

我确实使用正则表达式中的{2,3}来为除法器选择2或3个斜杠。但这在某种程度上似乎并不适用于“匹配所有”角色

有没有办法让正则表达式在不复制整个序列的情况下解析2或3个斜杠?

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

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

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

您丢失了名称,但可以在以后添加。

默认情况下,
+
量词是贪婪的,这意味着它将尝试匹配尽可能多的字符。因此,您希望使第一个
+
变懒,这样它就不会尝试通过添加
量词来匹配第一个
/
,您可以使
+
变懒:
+?

这将产生以下正则表达式:

((?<left>.+?)?)(?=(?<divider>[\/]{2,3}))([\/]{2,3})((?<right>.+)?)
((?。+?)(?=(?[\/]{2,3}))([\/]{2,3})((?。+)?)

是的,很简单,您需要使用
(?.*)
而不是
(?。+)?
为什么不能用
\s*/+\s*
拆分语句?除了使用
\s
之外,您还可以使用``(文字空格字符),因为
\s
还将匹配其他空白字符。在这里进行前瞻的目的是什么?重复与OP相同的错误。这是多余的,前瞻模式可以在消费模式中使用,整个正则表达式看起来更干净、更可读。另外,为什么要使用
(?。+?)?
?您需要至少1个字符,然后说“好的,匹配1个字符,但是1或0次”。说“匹配0个或更多字符”不是更自然吗?
(?*?)
?@Wiktor我只是调整了原始正则表达式来解决问题,并没有真正查看正则表达式的其他部分。再看一遍(看看你的答案),我明白你的意思了。虽然这也解决了问题中的问题,但我认为你的答案是迄今为止最好的答案。非常感谢你的明确解释和备选方案
$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 )
((?<left>.+?)?)(?=(?<divider>[\/]{2,3}))([\/]{2,3})((?<right>.+)?)