Назад | Перейти на главную страницу

Выполнение двух типов замены в .htaccess

Рассмотрим .htaccess файл, который должен преобразовать все символы подчеркивания в тире и заменить потенциальный .html суффикс с косой чертой в имени файла.

Пример URL от клиента: http://foo.com/a_b/c_d.html
Пример URL для перенаправления: http://foo.com/a-b/c-d/

Я использовал это правило, чтобы заменить .html суффикс:

RewriteRule ^(.*)\.html$ $1/ [R,L]

я нашел это потрясающее сообщение serverfault.SE для переписывания подчеркивания:

RewriteRule ^(.*)_(.*)_(.*)_(.*)$ /$1-$2-$3-$4 [R,L]
RewriteRule ^(.*)_(.*)_(.*)$ /$1-$2-$3 [R,L]
RewriteRule ^(.*)_(.*)$ /$1-$2 [R,L]

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

Это означает, что следующий код будет заменить .html суффикс только:

RewriteRule ^(.*)\.html$ $1/ [R,L]
RewriteRule ^(.*)_(.*)_(.*)_(.*)$ /$1-$2-$3-$4 [R,L]
RewriteRule ^(.*)_(.*)_(.*)$ /$1-$2-$3 [R,L]
RewriteRule ^(.*)_(.*)$ /$1-$2 [R,L]

И следующий код будет заменить подчеркивания только:

RewriteRule ^(.*)_(.*)_(.*)_(.*)$ /$1-$2-$3-$4 [R,L]
RewriteRule ^(.*)_(.*)_(.*)$ /$1-$2-$3 [R,L]
RewriteRule ^(.*)_(.*)$ /$1-$2 [R,L]
RewriteRule ^(.*)\.html$ $1/ [R,L]

Как должен .htaccess быть настроенным на замену как .html суффикс и подчеркивания?

Как упоминалось в комментариях, опубликованные вами директивы уже должны достичь того, что вам нужно, хотя и в двух отдельных перенаправлениях. Вам ничего не нужно делать, чтобы включить это поведение в .htaccess - вот как это работает.

Возможно, существует какой-то конфликт с другими директивами, но я изо всех сил пытаюсь представить, какой конфликт может привести к поведению, которое вы наблюдаете.

Однако вы можете объединить эти два перенаправления, так что будет только одно перенаправление. Например:

RewriteRule ^(.*)_(.*)_(.*)_(.*?)(?:/|\.html)?$ /$1-$2-$3-$4/ [R,L]
RewriteRule ^(.*)_(.*)_(.*?)(?:/|\.html)?$ /$1-$2-$3/ [R,L]
RewriteRule ^(.*)_(.*?)(?:/|\.html)?$ /$1-$2/ [R,L]

Это обрабатывает как URL-адреса, заканчивающиеся косой чертой, так и URL-адреса, которые не заканчиваются (если нет .html предоставляется расширение) - как указано в комментариях. Завершающая косая черта всегда включается в замена.

Дополнительные замечания:

(.*?) - The ? в последней захваченной группе делает регулярное выражение не жадным. Это необходимо, чтобы не захватывать косую черту в конце или .html расширение (если есть). Это осталось для следующей группы без захвата ...

(?:/|\.html)? - Это не захватывающий (?:) необязательная группа (конечная ?). Используя чередование, он соответствует либо завершающей косой черте, либо конечной .html расширение или вообще ничего.