将多个 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 - 未重写