dongre6227 2018-04-02 20:14
浏览 765
已采纳

PHP正则表达式:零个或多个空格不起作用

I'm trying to apply a regex constraint to a Symfony form input. The requirement for the input is that the start of the string and all commas must be followed by zero or more whitespace, then a # or @ symbol, except when it's the empty string.

As far as I can tell, there is no way to tell the constraint to use preg_match_all instead of just preg_match, but it does have the ability to negate the match. So, I need a regular expression that preg_match will NOT MATCH for the given scenario: any string containing the start of the string or a comma, followed by zero or more whitespace, followed by any character that is not a # or @ and is not the end of the string, but will match for everything else. Here are a few examples:

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

I would've thought for sure that /(^|,)\s*[^@#]/ would work, but it's failing in every case with 1 or more spaces and it appears to be because of the asterisk. If I get rid of the asterisk, preg_match('/(^|,)\s[^@#]/', '#yolo, @swag') does not match (as desired) when there's exactly once space, but as as soon as I reintroduce the asterisk it breaks for any quantity of spaces > 0.

My theory is that the regex engine is interpreting the second space as a character that is not in the character set [@#], but that's just a theory and I don't know what to do about it. I know that I could create a custom constraint to use preg_match_all instead to get around this, but I'd like to avoid that if possible.

  • 写回答

1条回答 默认 最新

  • doupu9251 2018-04-02 20:29
    关注

    You may use

    '~(?:^|,)\s*+[^#@]~'
    

    Here, the + symbol defines a *+ possessive quantifier matching 0 or more occurrences of whitespace chars, and disallowing the regex engine to backtrack into \s* pattern if [^@#] cannot match the subsequent char.

    See the regex demo.

    Details

    • (?:^|,) - either start of string or ,
    • \s*+ - zero or more whitespace chars, possessively matched (i.e. if the next char is not matched with [^#@] pattern, the whole pattern match will fail)
    • [^@#] - a negated character class matching any char but @ and #.
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题
  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入