Регулярное выражение PHP: ноль или более пробелов не работают

Я пытаюсь применить ограничение регулярного выражения к вводу формы 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 вместо этого, чтобы обойти это, но я бы хотел избежать этого, если это возможно.

Думаю нужен '~(?:^|,)\s*+[^#@]~'. Добавьте (?!$), если вам нужно условие «не в конце строки».

Wiktor Stribiżew 02.04.2018 22:23

@ WiktorStribiżew, это сработает, если я просто последую за * с +, как в вашем примере. Зачем нужен +?

Jimmy P 02.04.2018 22:25

Он выполняет сопоставление притяжательный падеж, т.е. нет возврата в шаблон \s*.

Wiktor Stribiżew 02.04.2018 22:26
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
3
1 320
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать

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

Здесь символ + определяет *+притяжательный квантификатор, соответствующий 0 или более вхождений пробельных символов, и запрещает механизму регулярных выражений возвращаться в шаблон \s*, если [^@#] не может соответствовать последующему символу.

См. демонстрация регулярного выражения.

Подробности

  • (?:^|,) - либо начало строки, либо ,
  • \s*+ - ноль или более пробельных символов, сопоставленных собственническим образом (т.е. если следующий символ не сопоставлен с шаблоном [^#@], все сопоставление с образцом не удастся)
  • [^@#] - инвертированный символьный класс, соответствующий любому символу, кроме @ и #.

Другие вопросы по теме