Вы должны использовать классы отрицательных символов :
^[^/]*/[^/]*/[^/]*/[^/]*$
[^/]
соответствует любому символу, кроме /
, поэтому мы представляем строку, содержащую три /
и все еще вокруг них.
В ваших регулярных выражениях .
может совпадать с чем угодно, включая /
, и хотя вы могли бы приблизить эквивалент отрицательных классов символов, используя отрицательные обратные выражения, вы не применили их должным образом к каждый .
, который у вас был: ^((?!\/).)*\/((?!\/).)*\/((?!\/).)*\/((?!\/).)*$
тоже работал бы, хотя он был бы менее производительным.
И не нужно избегать этих /
, они не являются метасимволами регулярных выражений. Вам может понадобиться экранировать их в языках или инструментах, которые используют /
в качестве разделителей, таких как синтаксис JavaScript * /pattern/
или подстановки s/search/replace/
в sed.