我分两个阶段做到了这一点。第一个是一组规则,提取一个参数,其他参数保持不变。然后我将其扩展为两个参数。规则本身并没有那么糟糕。只是很难弄清楚。
一个参数
这使用a
示例的参数。有4个条件:
由于问号与 & 号,最简单的做法是单独制定规则。事实证明,最后两个很容易组合成一个规则。
(注意:我正在使用 Helicon Ape 重写,它通常与 Apache 兼容。我遇到了一个问题,即 RewriteRule 问号需要在参数之前转义,例如,\?%2
我不知道这是否属实。)
# a
# ?a=foo
# Starts with a=, non-ampersand to the end.
# Suppress querystring with trailing question mark.
RewriteCond ${QUERY_STRING} ^a=([^&]+)$
RewriteRule ^/path/$ /path/%1/? [NC,R=301,L]
# a-other
# ?a=foo&b=bar, ?a=foo&b=bar&c=1
# Starts with a=, non-ampersand, ampersand, remaining required.
# Escape question mark so it doesn't include entire original querystring.
RewriteCond ${QUERY_STRING} ^a=([^&]+)&(.+)
RewriteRule ^/path/$ /path/%1/\?%2 [NC,R=301,L]
# other-a or other-a-other
# ?b=baz&a=qux, ?b=baz&c=1&a=qux
# ?c=1&a=foo&d=2&b=bar&e=3, ?z=4&c=1&a=foo&d=2&b=bar&e=3
# Starts with anything, ampersand, a=, non-ampersand, remaining optional.
# The remaining optional lets it follow with nothing, or with ampersand and more parameters.
# Escape question mark so it doesn't include entire original querystring.
RewriteCond ${QUERY_STRING} ^(.+)&a=([^&]+)(.*)$
RewriteRule ^/path/$ /path/$2/\?%1%3 [NC,R=301,L]
两个参数
将这两个参数放在一起有点棘手,但想法是重写a
,然后通过重写b
和重定向。要将这两个部分一起管理,请重写path
为temppath
then temppath2
,然后在完成后将其重写回path
。这确保了这些仅在两者a
都b
存在时运行。如果只有一个或另一个存在,那么它会跳过所有这些。(如果您还打算只处理一个,则可以进行调整。)
# Test cases:
# 1) /path/?a=foo&b=bar to /path/foo/bar
# 2) /path/?a=foo&b=bar&c=1 to /path/foo/bar?c=1
# 3) /path/?a=foo&b=bar&c=1&d=2 to /path/foo/bar?c=1&d=2
# 4) /path/?b=baz&a=qux to /path/qux/baz
# 5) /path/?b=baz&c=1&a=qux to /path/qux/baz/?c=1
# 6) /path/?c=1&b=baz&a=qux to /path/qux/baz/?c=1
# 7) /path/?c=1&d=2&b=baz&a=qux to path/qux/baz/?c=1&d=2
# 8) /path/?c=1&a=foo&d=2&b=bar&e=3 to /path/foo/bar/?c=1&d=2&e=3
# 9) /path/?z=4&c=1&a=foo&d=2&b=bar&e=3 to /path/foo/bar/?z=4&c=1&d=2&e=3
# Check for a and b (or b and a), rewrite to temp path and continue.
RewriteCond ${QUERY_STRING} (?:^|&)(?:a|b)=.+&(?:b|a)=.+$
RewriteRule ^/path/$ /temppath/ [NC]
# a
# ?a=foo
# This case isn't needed, since we test for a and b above.
# a-other
# 1) /temppath/?a=foo&b=bar to /temppath2/foo/?b=bar
# 2) /temppath/?a=foo&b=bar&c=1 to /temppath2/foo/?b=bar&c=1
# 3) /temppath/?a=foo&b=bar&c=1&d=2 to /temppath2/foo/?b=bar&c=1&d=2
# Starts with a=, non-ampersand, ampersand, remaining required.
RewriteCond ${QUERY_STRING} ^a=([^&]+)&(.+)$
RewriteRule ^/temppath/$ /temppath2/%1/\?%2 [NC]
# other-a or other-a-other
# 4) /temppath/?b=baz&a=qux to /temppath2/qux/?b=baz
# 5) /temppath/?b=baz&c=1&a=qux to /temppath2/qux/?b=baz&c=1
# 6) /temppath/?c=1&b=baz&a=qux to /temppath2/qux/?c=1&b=baz
# 7) /temppath/?c=1&d=2&b=baz&a=qux to /temppath2/qux/?c=1&d=2&b=baz
# 8) /temppath/?c=1&a=foo&d=2&b=bar&e=3 to /temppath2/foo/?c=1&d=2&b=bar&e=3
# 9) /temppath/?z=4&c=1&a=foo&d=2&b=bar&e=3 to /temppath2/foo/?z=4&c=1&d=2&b=bar&e=3
# Starts with anything, ampersand, a=, non-ampersand, remaining optional.
# The remaining optional lets it follow with nothing, or with ampersand and more parameters.
# Escape question mark so it doesn't include entire original querystring.
RewriteCond ${QUERY_STRING} ^(.+)&a=([^&]+)(.*)$
RewriteRule ^/temppath/$ /temppath2/%2/\?%1%3 [NC]
# b
# 1) /temppath2/foo/?b=bar to /path/foo/bar
# 4) /temppath2/qux/?b=baz to /path/qux/baz
# Starts with b=, non-ampersand to the end.
# Capture and use path after temppath2, since it has the a folder from above.
RewriteCond ${QUERY_STRING} ^b=([^&]+)$
RewriteRule ^/temppath2/(.*)/$ /path/$1/%1/? [NC,R=301,L]
# b-other
# 2) /temppath2/foo/?b=bar&c=1 to /path/foo/bar?c=1
# 3) /temppath2/foo/?b=bar&c=1&d=2 to /path/foo/bar?c=1&d=2
# 5) /temppath2/qux/?b=baz&c=1 to /path/qux/baz/?c=1
# Starts with b=, non-ampersand, ampersand, remaining required.
# Capture and use path after temppath2, since it has the a folder from above.
# Escape question mark so it doesn't include entire original querystring.
RewriteCond ${QUERY_STRING} ^b=([^&]+)&(.+)$
RewriteRule ^/temppath2/(.*)/$ /path/$1/%1/\?%2 [NC,R=301,L]
# other-b or other-b-other
# 6) /temppath2/qux/?c=1&b=baz to /path/qux/baz/?c=1
# 7) /temppath2/qux/?c=1&d=2&b=baz to /path/qux/baz/?c=1&d=2
# 8) /temppath2/foo/?c=1&d=2&b=bar&e=3 to /path/foo/bar/?c=1&d=2&e=3
# 9) /temppath2/foo/?z=4&c=1&d=2&b=bar&e=3 to /path/foo/bar/?z=4&c=1&d=2&e=3
# Starts with anything, ampersand, b=, non-ampersand, remaining optional.
# The remaining optional lets it follow with nothing, or with ampersand and more parameters.
# Capture and use path after temppath2, since it has the a folder from above.
# Escape question mark so it doesn't include entire original querystring.
RewriteCond ${QUERY_STRING} ^(.+)&b=([^&]+)(.*)$
RewriteRule ^/temppath2/(.*)/$ /path/$1/%2/\?%1%3 [NC,R=301,L]
在代码中可能更容易......