Как регулярное выражение соответствует строке альнумов и дефисов, но которая не начинается или не заканчивается дефисом?


У меня есть некоторый код, проверяющий строку от 1 до 32 символов, которая может содержать только альфа-цифры и дефисы ( ' - ' ), но не может начинаться или заканчиваться дефисом.

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

Сейчас псевдокод выглядит так:

if (match("/^[p{L}0-9][p{L}0-9-]{0,31}$/u", string) 
    and
    not match("/-$/", string))

   print "success!"

То есть я сначала проверяю, что строка имеет правильное содержимое, не имеет '-' и имеет правильную длину, а затем я запускаю другую строку. проверьте, чтобы убедиться, что он не заканчивается на" -".

Есть ли предложения по объединению этого в одно регулярное выражение PCRE?

Я пробовал использовать утверждения look-ahead / look-behind, но не смог заставить их работать.
2 2

2 ответа:

Попробуйте это регулярное выражение:

/^[\p{L}0-9](?:[\p{L}0-9-]{0,30}[\p{L}0-9])?$/u

И если вы хотите использовать утверждения типа look-around:

/^[\p{L}0-9][\p{L}0-9-]{0,31}$(?<!-)/u

Несколько альтернативный подход заключается в том, чтобы сохранить ваш класс символов в одном куске и быть точным в точках, где вы не хотите допускать дефис.

/^(?!-)[\p{L}0-9-]{1,32}(?<!-)$/Du

Также обратите внимание на модификатор D, который все, кажется, всегда забывают.

Наконец, просто чтобы быть уверенным, вы знаете, что \pL будет соответствовать гораздо больше, чем a-zA-Z, верно? Просто проверяю.