Самая простая проверка регулярного выражения, не соответствующего пробелу в начале или конце

#php #regex #preg-match

#php #регулярное выражение #preg-match

Вопрос:

Я пытаюсь найти самое простое регулярное выражение проверки (PCRE) для использования в методе preg_match () в PHP. Я хочу, чтобы это было как можно проще и по возможности избегать повторения.

Мои критерии соответствия в словах:

  • Разрешить один или несколько символов (это подразумевает, что строка должна содержать в общей сложности 1 символ и более) из следующего списка:

     a-zA-Z0-9  amp;-
      
  • Не разрешать пробел в начале или конце

Возможно, мне не хватает знаний о регулярных выражениях, но то, что я получаю без второго критерия пробела, это:

     /^[a-zA-Z0-9  amp;-] $/
  

Чтобы не совпадать с пробелом, я думаю о чем-то вроде

     /^[^ ] [a-zA-Z0-9  amp;-] [^ ] $/
  

но для этой фактической части потребуется более 3 символов.

Если я сделаю

     /^[^ ]*[a-zA-Z0-9  amp;-] [^ ]*$/
  

это также не будет работать постоянно, я полагаю, это связано с «жадностью» средней части, но я действительно пытался исследовать, как сделать это правильно, но безуспешно.

Благодарен за любой совет или указатель в правильном направлении!

Комментарии:

1. Вы знаете, что trim() делает, верно?

2. [^ ] может быть заменен на S , который является общим «не пробелом».

3. @CodeCaster: Хе-хе, да, я очень хорошо понимаю, что делает trim(). Это регулярное выражение проверки перед передачей его в подсистему, если оно не соответствует определенному шаблону, строка должна быть отклонена, поэтому я не могу просто обрезать () это MarcB: Я знаю, но пробел — это единственный символ пробела, который я могу разрешить в строке, поэтому, к сожалению, это не помогает мне, как я это вижу?

Ответ №1:

Вы хотите обернуть оба [^ ] условия в утверждения. Слева (?=) и (?<=) в конце.

  /^(?=[^ ])[a-zA-Z0-9  amp;-] (?<=S)$/
  

Я думаю, этого достаточно, если вы протестируете только по одному символу без пробела на каждом конце. Тогда уже гарантируется, что содержимое начинается с буквы или другого разрешенного символа.

Смотрите http://www.regular-expressions.info/lookaround .html для хорошего объяснения.

Комментарии:

1. На самом деле это не соответствует требованиям его проверки. [^ ] может соответствовать любому символу, который не является пробелом, включая /? _= чего он не хочет.

2. Спасибо, Марио! Когда я начал читать об утверждениях, я придумал следующее регулярное выражение, которое, похоже, является решением: ^(?=[^ ])[ a-zA-Z0-9 amp;-] (?<=[^ ])$ @ Thorbear: Поправьте меня, если я ошибаюсь, но все, что я хочу убедиться, это то, что строка не начинается и не заканчивается пробелом, а затем содержит один или несколько символов в списке символов — и, как я понимаю, мое регулярное выражение выше заботится об этом? Я имею в виду, даже если положительное утверждение соответствует вводному /? _ или что-то еще, оно все равно не будет разрешено в списке символов, следующих следующим. Или я что-то недопонимаю?

3. @Thorbear: Он сказал только пробелы. Но, конечно, любое другое количество исключений может быть добавлено к [^ ] классу отрицаемых символов. Даже если это изначально соответствует каким-либо странным символам ?_ö:@ — следующий класс символов не разрешил бы их. Магия утверждений заключается в том, что они работают в сочетании с фактическими разделами сопоставления / захвата.

4. @mario Кажется, вы правы. Я был слишком сосредоточен на том факте, что [^ ] соответствует любому символу, не являющемуся пробелом, чтобы помнить, как это работает в режиме ожидания. Мои извинения.

Ответ №2:

Похоже, вы не хотите, чтобы вам просто давали шаблон, поэтому я попытаюсь дать несколько советов вместо этого.

Вы хотите сопоставить строку, которая начинается с любого символа из списка [a-zA-Z0-9 amp;-] , вы хотите, чтобы за ней следовал любой символ из того же списка или пробел неограниченной длины.

Чтобы сделать шаблон как можно короче, вы можете помнить, что он * совпадает от 0 до неограниченного количества раз, что означает, что все, что вы ставите перед ним, на самом деле вообще не должно там появляться; шаблон (ab*) может совпадать ab или abab или aaa , но никогда ba

Ответ №3:

Ваш класс main character включает символ пробела, поэтому, даже если вы явно исключаете пробелы с [^ ]* частью, вы все равно ДОПУСКАЕТЕ пробелы с вашим main [a-z...] , так что вы фактически сводите на нет всю цель регулярного выражения.

по сути, вы установили знак «парковка запрещена» с надписью «парковка запрещена в любое время. разрешенная парковка 9-5».


продолжение: то, что вы хотите, — это отрицательные утверждения:

 /^(?<!s)[a-z.....](?>!s)$/
  

Первое — это отрицательное ( ! ) контрольное утверждение ( < ), которое гласит: «не допускайте пробел ( s ) перед тем, что следует ( [a-z...] ). Другое такое же, но с отрицательным прогнозом ( > ).

Комментарии:

1. Да, я понимаю это, но не то, как выразить то, что я хочу, т. Е. Разрешить пробелы, если они не находятся в начале строки (с предпочтением минимального повторения). Я мог бы, конечно, разделить это на два регулярных выражения / проверки, но я просто использую его в файле конфигурации, и это только усложнило бы ситуацию.

Ответ №4:

Я бы сосредоточился на том, что требуется.

^(?i)[a-z0-9 amp;-][a-z0-9 amp;-]*(?<=[a-z0-9 amp;-])$

Комментарии:

1. Вероятно, это рабочее предложение, но моей целью было минимизировать повторение, и лучшим решением, которое я нашел, было ^(?= [^ ])[a-zA-Z0-9 amp;-] (?<=[^ ])$ чтобы соответствовать всем моим требованиям. Спасибо за ваше участие, хотя sln!