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