#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!