Итак, окончательное решение EDITED (для вашего связанного .htaccess):
RewriteCond %{REQUEST_FILENAME} ethical [NC]
RewriteCond %{QUERY_STRING} (^|&|%26|%20)ethical(=|%3D)([^&]+) [NC]
RewriteRule .* /catalogsearch/result/?q=%3 [L,R]
Если я использую термины «категория», как в этом текущем вопросе:
RewriteCond %{REQUEST_FILENAME} category [NC]
RewriteCond %{QUERY_STRING} (^|&|%26|%20)category(=|%3D)([^&]+) [NC]
RewriteRule .* /categorysearch/result/?q=%3 [L,R]
Но первый более понятен, слово категория используется не везде. Если вы хотите добавить преобразование в нижнем регистре, мы даже сделаем:
# outside of a Directory section
RewriteMap lowercase int:tolower
# in a Directory section (not a .htaccess)
RewriteCond %{REQUEST_FILENAME} category [NC]
RewriteCond %{QUERY_STRING} (^|&|%26|%20)category(=|%3D)([^&]+) [NC]
RewriteRule .* /catalogsearch/result/?q=${lowercase:%3} [L,R]
Но, как прокомментировал , этот последний с tolower не мог работать в .htaccess - в любом случае .htaccess плох, действительно, для выступлений, вы должны действительно подумать о настройке AllowOverride None и переместить все это в виртуальном хосте И такие приятные вещи, как rewriteMaps не могут работать с файлами .htaccess.
Так что теперь я объясню правила. Во-первых, основная проблема в вашей ситуации состоит в том, что все, что после "?" , это query_string , а не запрашиваемое имя файла . И большинство rewriteRules пытаются работать с запрошенным именем файла. Итак, я сначала проверяю, что мы находимся на целевом имени файла:
RewriteCond %{REQUEST_FILENAME} category [NC]
Затем мы будем работать над строкой запроса (все после знака вопроса). Мы могли бы написать что-то более простое, как это:
RewriteCond %{REQUEST_FILENAME} category [NC]
RewriteCond %{QUERY_STRING} ^category=(.+) [NC]
RewriteRule .* /catalogsearch/result/?q=${lowercase:%1} [L,R]
Чтобы поймать все после? Category = в переменной% 1, доступной для RewriteRule. Но у параметра QUERY_STRING есть несколько проблем, давайте попробуем немного повеселиться с ним:
- Для этого параметра декодирование URL еще не выполнено
- категория, возможно, не первый параметр в списке параметров
- возможно, даже не последний (& foo = bar)
- у вас может быть несколько пробелов до
EDITED
Мой первый ответ был:
RewriteCond %{REQUEST_FILENAME} category [NC]
RewriteCond %{QUERY_STRING} [^|&|%26|%20][category](=|%3D)([^&]+) [NC]
RewriteRule .* /catalogsearch/result/?q=${lowercase:%2} [L,R]
Если [^|&|%26|%20]
уловить тот факт, что это может быть начальный параметр или параметр после & или пробела, %26
является & urlencoded.
Но это было неправильно , благодаря комментарию @mootinator, я проверил немного больше, [категория] соответствует 'категории', но также 'atcatcategory' и любой комбинации букв этих тезисов.
RewriteCond %{QUERY_STRING} category(=|%3D)([^&]+) [NC]
Соответствует аргументу 'category', удаление ^
позволяет разместить этот аргумент в любом месте. Но это также соответствует аргументу с именем subcategory
. Поэтому первая буква должна быть пробелом или & (или началом строки запроса).
Это была причина для [^|&|%26|%20]
, означая для меня начало цепочки ИЛИ или пробела или & в урленкодированном. Но это было также неправильно , ^
внутри []
означает отрицание. Поэтому нам нужно использовать здесь также соответствующие скобки: (^|&|%26|%20)
, теперь это работает, единственная проблема в том, что значение аргумента теперь% 3, а не% 2
Затем мы ловим слово (категория), чтобы быть точным, мы должны фактически поймать его буква за буквой с заглавной, строчной и urlencoded версией буквы в нижнем и верхнем регистре, что-то вроде ужасного [c|C|%43|%63][a|A|%61|%41][t|T|%74|...]to be continued
- и, возможно, я должен использовать скобки вместо скобок, черт возьми, проверьте список символов в кодировке здесь .
(=|%3D)
- это символ '=', кодированный или нет. Я мог бы использовать [=|%3D]
, но %3D
не подходит в этом случае, я не понимаю, почему (mod_rewrite - страна странных вещей) . Из-за этой первой подходящей круглой скобки мы должны будем использовать переменную% 2, а не% 1.
И тогда у нас есть хороший ([^&]+)
, который означает что угодно, но не '&'.
После этих условий мы применяем RewriteRule. Мы берем все (это .*
) и перенаправляем его на /catalogsearch/result/?q=%2
, где используем %3
, а не $1
или $3
, так как мы ничего не записываем в rewriteRule, но при условии до (%3
) это третья записанная информация о последнем условии, поэтому ([^&]+)
).
Если вы добавите флаг QSA ([L, R, QSA]) в rewriteRule, вы даже вернете другие параметры в окончательной строке запроса, так что:
ethical?bar=toto& ethical=Foo&zorglub=titi
=> is redirected to
catalogsearch/result/?q=foo&bar=toto&%2520ethical=Foo&zorglub=titi
А если я поиграюсь с небольшой кодировкой URL:
ethical?bar=toto%26 ethical%3DFoo&zorglub=titi
=> is redirected to
catalogsearch/result/?q=foo&bar=toto%2526%2520ethical%253DFoo&zorglub=titi
Но это не конец игры, я позволю вам разобраться со всеми проблемами урлен-кодирования, которые могут возникнуть, если вы захотите обнаружить все изменения значения Foo и смешать их с tolower (здесь он не работает).Возможно, у вас даже не будет проблем с закодированными URL в ваших параметрах или дополнительных атрибутах, но это было забавно: -)