.htaccess rewrite regex: сопоставить ничего, кроме "index"

Я пытаюсь создать правило, используемое в файле .htaccess, чтобы соответствовать , но конкретной строке, в данном случае: index.

Я подумал, что сначала нужно будет сопоставить эту специальную строку и использовать [L], но это не работает,
и это должно быть возможно с использованием следующего регулярного выражения, но оно вызывает ошибку 500.

Я хочу совместить:

  • pagename1
  • pagename2/все
  • pagename3/234/все
  • о
  • контакт-нам
  • (и т.д.)

но не

  • Индекс /123
  • Индекс/124/все

(BTW "index" - это имя файла без расширения, а не мой выбор, это работа)

^(?!index)[\w/\-]+

Я предполагаю, что реализация Apache регулярного выражения не справляется с правилом (?!xxx).

Любая помощь/предложения будут высоко оценены.

Ответ 1

Вы можете использовать RewriteCond для этого, например:

RewriteCond %{REQUEST_URI} !^index
RewriteRule (.*) index.php?what=$1

Это будет переписывать каждый URL-адрес, который не начинается с индекса. Если вы хотите, чтобы он не попадал в URL-адрес, удалите ^

Ответ 2

(Пожалуйста, прочитайте комментарии. Я сомневаюсь в этом, и я никогда не сталкивался с проблемами, в то время как он дает более чистые файлы .htaccess, но: использование RewriteCond может предпочтительнее использования RewriteRule с тире, из-за того, как обрабатываются набор правил?)

Просто используйте RewriteRule следующим образом, чтобы не переписывать (тире) и останавливать последующую переписывание ([L]) для всего, что начинается с index/:

# Do not rewrite anything that starts with index/
RewriteRule ^index/ - [L]

После этого сделайте любое переписывание, которое вам нравится.

Или, может быть, даже ограничьте сначала несколько:

# Do not rewrite files, directories or symbolic links 
RewriteCond %{REQUEST_FILENAME} -f [OR] 
RewriteCond %{REQUEST_FILENAME} -d [OR] 
RewriteCond %{REQUEST_FILENAME} -l 
RewriteRule . - [L]

Ответ 3

Apache использовал три различные реализации регулярных выражений. Первой была System V8, поскольку Apache 1.3 использовали POSIX ERE, а с Apache 2 они использовали PCRE. И только PCRE поддерживает прогнозные утверждения. Поэтому вам нужно, чтобы Apache 2 использовал это правило.

Но теперь на ваш вопрос. Если вы используете это правило:

RewriteRule ^index/ - [L]

все, что начинается с /index/, должно быть уловлено этим правилом, и никакое другое правило не должно применяться.

Но если это не работает, попробуйте следующее:

RewriteRule !^index/ …

Опять же, это правило будет применяться к любому запросу, путь URL-адреса которого не начинается с /index/.

И если вы хотите захватить что-либо из URL-адреса, используйте условие RewriteCond для проверки самого полного пути URL-адреса (%{REQUEST_URI}) или просто совпадения одной из ваших групп шаблонов:

RewriteCond %{REQUEST_URI} !^/index/
RewriteRule (.*) …
# or
RewriteCond $1 !^index$
RewriteRule ^([^/]+)/(.*) …