PHP正则表达式:零个或多个空格无效

PHP正则表达式:零个或多个空格无效,php,regex,symfony,Php,Regex,Symfony,我试图对Symfony表单输入应用regex约束。输入的要求是,字符串和所有逗号的开头必须后跟零个或多个空格,然后是一个或@符号,除非是空字符串 据我所知,没有办法告诉约束使用preg_match_all而不是preg_match,但它确实有能力否定匹配。因此,我需要一个preg_match在给定场景中不匹配的正则表达式:任何包含字符串开头或逗号的字符串,后跟零个或多个空格,后跟任何不是a或@且不是字符串结尾的字符,但将匹配其他所有字符。以下是几个例子: preg_match(..., '');

我试图对Symfony表单输入应用regex约束。输入的要求是,字符串和所有逗号的开头必须后跟零个或多个空格,然后是一个或@符号,除非是空字符串

据我所知,没有办法告诉约束使用preg_match_all而不是preg_match,但它确实有能力否定匹配。因此,我需要一个preg_match在给定场景中不匹配的正则表达式:任何包含字符串开头或逗号的字符串,后跟零个或多个空格,后跟任何不是a或@且不是字符串结尾的字符,但将匹配其他所有字符。以下是几个例子:

preg_match(..., '');              // No match
preg_match(..., '#yolo');         // No match
preg_match(..., '#yolo,  #swag'); // No match
preg_match(..., '#yolo,@swag');   // No match
preg_match(..., '#yolo, @swag,'); // No match

preg_match(..., 'yolo');        // Match
preg_match(..., 'swag,#yolo');  // Match
preg_match(..., '@swag, yolo'); // Match
我本以为/^ |,\s*[^@]/肯定会起作用,但每次都有1个或多个空格,而且似乎是因为星号。如果我去掉星号,preg_match'/^ |,\s[^@]/',yolo,@swag'在正好有一个空格的情况下并不匹配,但一旦我重新引入星号,它就会因任何大于0的空格数量而中断

我的理论是,正则表达式引擎将第二个空格解释为不在字符集[@]中的字符,但这只是一个理论,我不知道该怎么办。我知道我可以创建一个自定义约束来使用preg_match_all来解决这个问题,但如果可能的话,我希望避免这种情况。

您可以使用

'~(?:^|,)\s*+[^#@]~'
这里,+符号定义了一个*+匹配0个或更多出现的空白字符,如果[^@]无法匹配后续字符,则不允许正则表达式引擎回溯到\s*模式

细节

?:^ |,-字符串的开头或, \s*+-零个或多个空格字符,按所有格匹配,即如果下一个字符与[^@]模式不匹配,则整个模式匹配将失败 [^@]-与除@和之外的任何字符匹配的否定字符类。
我想你需要“~?:^ |,\s*+[^@]~”。追加如果您需要not在字符串条件的末尾。@WiktorStribiżew如果我只是在*后面加上+就行了,就像您的示例中一样。为什么+是必需的?它使匹配具有所有格,即没有回溯到\s*模式。