Попробуйте это:
(?:[\w\-](?<!_))+
Он выполняет простое сопоставление со всем, что закодировано как \ w (или тире), а затем имеет вид сзади нулевой ширины, который гарантирует, что только что подобранный символ не является подчеркиванием.
В противном случае вы можете выбрать это:
(?:[^_\W]|-)+
, который является подходом, основанным на множестве (обратите внимание на прописную букву W)
ОК, я очень повеселился с юникодом в php-аромате PCRE: D
Пикабу говорит, что доступно простое решение:
[\p{L}\p{N}\-]+
\ p {L} соответствует любому юникоду, который квалифицируется как буква (примечание: не символ слова, следовательно, нет подчеркивания), в то время как \ p {N} соответствует всему, что выглядит как число (включая римские цифры и более экзотические вещи ).
\ - это просто сбежавший тире. Хотя это не является строго необходимым, я стараюсь избегать тире в классах символов ... Обратите внимание, что в юникоде есть десятки различных тире, что дает следующую версию:
[\p{L}\p{N}\p{Pd}]+
Где "Pd" - это пунктуация, включая, но не ограничиваясь, нашей минус-тире. (Обратите внимание, здесь снова нет подчеркивания).