将多个 RewriteRule 指令组合成 .htaccess 中的单个规则
Combine several RewriteRule directives into a single rule in .htaccess
我在 .htaccess
中有以下 RewriteRule
指令:
RewriteRule ^work/([a-zA-z0-9\-]*).html$ work.php?go= [L]
RewriteRule ^work/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*).html$ work.php?go=&sub= [L]
RewriteRule ^work/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*).html$ work.php?go=&sub=&pid= [L]
RewriteRule ^work/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*).html$ work.php?go=&sub=&pid=&pad= [L]
RewriteRule ^work/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*).html$ work.php?go=&sub=&pid=&pad=&id= [L]
一切正常。
但是有没有人知道我如何将所有这一行作为一条规则只放在一行中?
您不能将它们缩减为一条规则并使其“完全”相同地工作。在单个规则中,所有 URL 参数将始终被定义(但可能为空)。使用您当前的规则集, URL 参数仅在需要时才定义 - 细微差别。如果您对这种微小的差异感到满意(您应该如此),那么这些规则可以简化为一条规则。
首先,我建议对您现有的正则表达式进行一些小改动:
我会假设最后的路径段,即。 .html
之前的“文件名”是必需的。目前,您允许 /work/.html
(这会导致 go
URL 参数为空)。
其他 URL 参数应接受 1 个或多个字符,而不是 0 个或多个。它实际上不会“匹配” 0 个字符,因为多个连续的
在与 RewriteRule
模式 .
匹配的 URL 路径中减少了斜杠
我会简化您在路径段中匹配的正则表达式。从 [a-zA-z0-9\-]
到 [\w-]
。这与之前的匹配相同加上下划线 (_
)。在字符 class.
的开头或结尾使用时,无需对文字连字符进行反斜杠转义
由于您在所有路径段中匹配相同的模式,因此“组合”规则不会变得过于复杂,因为您可以附加另一个路径段并使其对于每个额外的 URL 参数都是可选的(所有前面的路径段必须首先匹配)。但是,如果您在每个路径段中匹配不同的正则表达式,它会复杂得多 - 这将涉及很多 nested 组以保持正确的匹配顺序。
考虑到以上几点,您的 5 条规则可以合并为以下一条规则:
RewriteRule ^work/([\w-]+)(?:/([\w-]+))?(?:/([\w-]+))?(?:/([\w-]+))?(?:/([\w-]+))?\.html$ work.php?go=&sub=&pid=&pad=&id= [L]
在第一个 mandatory 路径段(即 ([\w-]+)
)之后,正则表达式 (?:/([\w-]+))?
只是附加到每个额外的 optional路径段。
导致以下重写:
/work/.html
- 未重写
/work/abc.html
-> work.php?go=abc&sub=&pid=&pad=&id=
/work/abc/def.html
-> work.php?go=abc&sub=def&pid=&pad=&id=
/work/abc/.html
- 未重写
/work/abc/def/ghi/jkl/mno.html
-> work.php?go=abc&sub=def&pid=ghi&pad=jkl&id=mno
/work/abc/def/ghi/jkl/mno/.html
- 未重写
/work/abc/def/ghi/jkl/mno/pqr.html
- 未重写
我在 .htaccess
中有以下 RewriteRule
指令:
RewriteRule ^work/([a-zA-z0-9\-]*).html$ work.php?go= [L]
RewriteRule ^work/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*).html$ work.php?go=&sub= [L]
RewriteRule ^work/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*).html$ work.php?go=&sub=&pid= [L]
RewriteRule ^work/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*).html$ work.php?go=&sub=&pid=&pad= [L]
RewriteRule ^work/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*).html$ work.php?go=&sub=&pid=&pad=&id= [L]
一切正常。
但是有没有人知道我如何将所有这一行作为一条规则只放在一行中?
您不能将它们缩减为一条规则并使其“完全”相同地工作。在单个规则中,所有 URL 参数将始终被定义(但可能为空)。使用您当前的规则集, URL 参数仅在需要时才定义 - 细微差别。如果您对这种微小的差异感到满意(您应该如此),那么这些规则可以简化为一条规则。
首先,我建议对您现有的正则表达式进行一些小改动:
我会假设最后的路径段,即。
.html
之前的“文件名”是必需的。目前,您允许/work/.html
(这会导致go
URL 参数为空)。其他 URL 参数应接受 1 个或多个字符,而不是 0 个或多个。它实际上不会“匹配” 0 个字符,因为多个连续的 在与
匹配的 URL 路径中减少了斜杠RewriteRule
模式 .我会简化您在路径段中匹配的正则表达式。从
的开头或结尾使用时,无需对文字连字符进行反斜杠转义[a-zA-z0-9\-]
到[\w-]
。这与之前的匹配相同加上下划线 (_
)。在字符 class.
由于您在所有路径段中匹配相同的模式,因此“组合”规则不会变得过于复杂,因为您可以附加另一个路径段并使其对于每个额外的 URL 参数都是可选的(所有前面的路径段必须首先匹配)。但是,如果您在每个路径段中匹配不同的正则表达式,它会复杂得多 - 这将涉及很多 nested 组以保持正确的匹配顺序。
考虑到以上几点,您的 5 条规则可以合并为以下一条规则:
RewriteRule ^work/([\w-]+)(?:/([\w-]+))?(?:/([\w-]+))?(?:/([\w-]+))?(?:/([\w-]+))?\.html$ work.php?go=&sub=&pid=&pad=&id= [L]
在第一个 mandatory 路径段(即 ([\w-]+)
)之后,正则表达式 (?:/([\w-]+))?
只是附加到每个额外的 optional路径段。
导致以下重写:
/work/.html
- 未重写/work/abc.html
->work.php?go=abc&sub=&pid=&pad=&id=
/work/abc/def.html
->work.php?go=abc&sub=def&pid=&pad=&id=
/work/abc/.html
- 未重写/work/abc/def/ghi/jkl/mno.html
->work.php?go=abc&sub=def&pid=ghi&pad=jkl&id=mno
/work/abc/def/ghi/jkl/mno/.html
- 未重写/work/abc/def/ghi/jkl/mno/pqr.html
- 未重写