Возможно ли это достичь с помощью регулярных выражений?

#regex #apache #.htaccess #redirect #centos

#регулярное выражение #apache #.htaccess #перенаправление #centos

Вопрос:

У меня странный URL-адрес, дающий статус 200 там, где этого не должно быть. Он должен просто выдать ошибку 404. Есть ли перенаправление 404, которое я могу использовать в htaccess для этого?

Хорошие URL-адреса выглядят так

 www.example.com/this-is-static/anytext
  

или

 www.example.com/this-is-static/anytext/alsoanytext_123
  

или

 www.example.com/this-is-static/anytext/alsoanytext_123-123
  

или

 www.example.com/this-is-static/anytext/alsoanytext/alsoanytextagain_123-123
  

Неверный URL-адрес выглядит следующим образом

 www.example.com/this-is-static/anytext/alsoanytext
  

Примечание: слова anytext, alsoanytext и alsoanytextagain являются случайными подстановочными знаками * … это могут быть любые слова. Числа «123» могут быть любой комбинацией чисел

» This-is-static» не меняется

Итак, как вы можете видеть, неверный URL-адрес не содержит части «_XXXXXX»

В принципе, мне это нужно, чтобы, если URL-адрес попадал в подпапку «also anytext» (и далее), но после него не было подчеркивания, перенаправление на 404

Надеюсь, это имеет смысл

РЕДАКТИРОВАТЬ 2:

Я не уверен, что приведенный ниже метод будет работать, поскольку регулярное выражение соответствует всем URL-адресам, за исключением «плохого», что делает это невозможным с помощью htaccess без установки новых правил для всех других вложенных папок.

Просто для упрощения, используя это в качестве примера, ( https://regexr.com/5e5fd ) как бы мы получили линию

www.example.com/this-is-static/anytext/alsoanytext

чтобы быть единственным совпадением

Ответ №1:

В этом есть два аспекта… регулярное выражение и Apache .htaccess .

 www.example.com/this-is-static/[^/s]*(?:/[^_s] _.*)?$
  

@MarcSances, похоже, создал регулярное выражение, которое соответствует «хорошим» URL-адресам ( 1). (Хотя нужно ли вам s (пробел) быть частью отрицаемого символьного класса?) Используя mod_rewrite, вы можете просто отменить это регулярное выражение (с ! префиксом), чтобы не совпадать с хорошими URL-адресами (т.е. успешно для «плохих» URL-адресов).

В файлах конфигурации Apache вам не нужно использовать обратную косую черту, поскольку косая черта не имеет особого значения (нет разделителей регулярных выражений, за исключением пробелов в качестве разделителей аргументов). (К сожалению, regexr.com это не позволяет вам изменять разделители регулярных выражений ?!)

Обратите внимание, что с RewriteRule помощью директивы вы сопоставляете только URL-путь (за вычетом префикса косой .htaccess черты), а не имя хоста.

 RewriteRule ^this-is-statis/[^/s]*(?:/[^_s] _.*)?$ error.php [R=404,L]
  

Когда вы указываете статус, отличный от 3xx для R флага, строка подстановки (т.е. error.php в этом примере) игнорируется. Вместо этого вы должны указать один дефис ( - ), чтобы явно указать «без подстановки». Кроме того, L флаг является излишним, он подразумевается.

Итак, чтобы отрицать это выражение, оно станет:

 RewriteRule !^this-is-statis/[^/]*(?:/[^_] _.*)?$ - [R=404]
  

Будет обслуживать 404 ErrorDocument для запрошенных URL-адресов, которые не соответствуют «хорошим URL-адресам».


 /this-is-static/anytext/alsoanytext
  

Однако, похоже, вы должны иметь возможность напрямую сопоставлять «плохой» URL-адрес, если alsoanytext только он сам не может законно содержать символы подчеркивания ( _ ). Например:

 RewriteRule ^this-is-static/[^/] /[^/_] $ - [R=404]
  

Комментарии:

1. Спасибо за подробный ответ, и последнее правило сделало то, что должно было делать.

Ответ №2:

Используйте следующее выражение с группой, не подлежащей захвату:

 www.example.com/this-is-static/[^/s]*(?:/[^_s] _.*)?$
  

Объяснено:

  • Сопоставьте все www.example.com/this-is-static / регулярно.
  • Сопоставьте все, кроме косой черты ( [^/s]* ).
  • ?: Группа без захвата для материала /alsoanytext. ? Квантификатор в конце делает эту часть необязательной, поэтому /anytext без чего-либо еще также соответствует.
  • / Теперь сопоставьте косую черту.
  • [^_s] Сопоставьте все, кроме подчеркивания.
  • Совпадение подчеркивания _ .
  • Сопоставьте что-нибудь еще, кроме разрывов строк .* . Используйте предпочитаемый вами метод для сопоставления остальной части URL, если сопоставление all не подходит.
  • Сопоставьте конец строки $ . Требуется убедиться, что ничего не следует /anytext , кроме правильно сформированного /alsoanytext_whatever . В противном случае у вас может быть частичное совпадение, когда используется неправильный URL (поскольку начало будет совпадать с /anytext ).

Вы можете увидеть это в regexr.

Комментарии:

1. Спасибо за это, но мне нужно было прояснить вопрос (что я и сделал только что) слова «anytext» символизируют подстановочные знаки. Также добавлен еще один возможный «хороший URL»

2. Хорошо, я обновил ответ в соответствии с вашими требованиями.

3. Еще раз спасибо, но у меня возникли проблемы с указанием правилу принимать все URL-адреса, НЕ соответствующие этому регулярному выражению, и иметь их 404, я попробовал что-то вроде RewriteRule ^this-is-statis /[^/s]*(?:/[^_ s] _.*)? $ error.php [R=404,L] но это явно приведет к обратному результату, чем я хочу

4. тогда используйте отрицательный прогноз со всем моим ответом.

5. Потому что в regexr у меня было много URL-адресов для сопоставления, и если вы не отменяете пробелы / разрывы строк, класс символов протекает через следующую строку. Я знаю, что это не требуется в реальной ситуации, но я включил его в соответствие с ответом regexr.