Я пытаюсь применить ограничение регулярного выражения к вводу формы Symfony. Требование для ввода состоит в том, что за началом строки и всеми запятыми должны следовать ноль или более пробелов, а затем символ # или @, за исключением случаев, когда это пустая строка.
Насколько я могу судить, нет способа указать ограничение на использование preg_match_all вместо просто preg_match, но у него есть возможность свести на нет совпадение. Итак, мне нужно регулярное выражение, которое preg_match НЕ СООТВЕТСТВУЕТ данному сценарию: 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, но будет соответствовать всему остальному. Вот несколько примеров:
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*[^@#]/ будет работать, но он не работает в каждом случае с одним или несколькими пробелами, и, похоже, из-за звездочки. Если я избавлюсь от звездочки, preg_match('/(^|,)\s[^@#]/', '#yolo, @swag') не будет соответствовать (по желанию), когда есть ровно один пробел, но как только я снова введу звездочку, он сломается для любого количества пробелов> 0.
Моя теория состоит в том, что механизм регулярных выражений интерпретирует второй пробел как символ, которого нет в наборе символов [@#], но это всего лишь теория, и я не знаю, что с этим делать. Я знаю, что мог бы создать собственное ограничение для использования preg_match_all вместо этого, чтобы обойти это, но я бы хотел избежать этого, если это возможно.
@ WiktorStribiżew, это сработает, если я просто последую за * с +, как в вашем примере. Зачем нужен +?
Он выполняет сопоставление притяжательный падеж, т.е. нет возврата в шаблон \s*.






Вы можете использовать
'~(?:^|,)\s*+[^#@]~'
Здесь символ + определяет *+притяжательный квантификатор, соответствующий 0 или более вхождений пробельных символов, и запрещает механизму регулярных выражений возвращаться в шаблон \s*, если [^@#] не может соответствовать последующему символу.
См. демонстрация регулярного выражения.
Подробности
(?:^|,) - либо начало строки, либо ,\s*+ - ноль или более пробельных символов, сопоставленных собственническим образом (т.е. если следующий символ не сопоставлен с шаблоном [^#@], все сопоставление с образцом не удастся)[^@#] - инвертированный символьный класс, соответствующий любому символу, кроме @ и #.
Думаю нужен
'~(?:^|,)\s*+[^#@]~'. Добавьте(?!$), если вам нужно условие «не в конце строки».