iis url-rewrite 中奇怪的正则表达式错误
Weird regex bug in iis url-rewrite
这是我的模式:
^(\w{2}-\w{2})/questions(?:/(\w+))?(?:/(\d+))?(?:/.*?)?$
这些是我正在测试的内容:
en-us/questions/ask
en-us/questions/newest/15
en-us/questions/12/just-a-text-to-be-ignored
完美运行,这里是演示:
https://regex101.com/r/yC3tI8/1
但以下重写规则:
<rule name="en-us questions" enabled="true" stopProcessing="true">
<match url="^(\w{2}-\w{2})/questions(?:/(\w+))?(?:/(\d+))?(?:/.*?)?$" />
<action type="Rewrite" url="/questions.aspx?lang={R:1}&tab={R:2}&pid={R:3}" />
</rule>
当我将 link en-us/questions/newest
重定向到:/questions.aspx?lang=en-us&tab=&pid=
这有什么问题吗?现在大约 5 个小时,我只是在复习同样的东西
请注意,您有三个延迟捕获:
(?:/(\w+))?
(?:/(\d+))?
(?:/.*?)?
asp.net's regex implementation 将 ?
解释为:
In addition to specifying that a given pattern may occur exactly 0 or 1 time, the ?
character also forces a pattern or subpattern to match the minimal number of characters when it might match several in an input string.
所以 asp.net 没有为 1 分配任何字符,没有为 2 分配任何字符,并收集其余字符3.
要使用贪婪匹配而不是惰性匹配 ?
强制使用:{0,1}
所以你的正则表达式应该是这样的:
^(\w{2}-\w{2})/questions(?:/(\w+)){0,1}(?:/(\d+)){0,1}(?:/.*?)?$
由于您有三种可能的 url 结局最终会影响重写 url 的结果,您可以设置一个全面的规则 希望 匹配你想要的一切,或者你可以设置三个规则来相应地处理每个规则:
一条规则:
^(\w{2}-\w{2})/questions/(\w+)/?(\d+)?.*$
https://regex101.com/r/dN8bM9/1 - tries to handle all cases
<rule name="en-us questions" enabled="true" stopProcessing="true">
<match url="^(\w{2}-\w{2})/questions/(\w+)/?(\d+)?.*$" />
<action type="Rewrite" url="/questions.aspx?lang={R:1}&tab={R:2}&pid={R:3}" />
</rule>
* 注意:原始模式未能捕获第二组的一个可能原因是包含 (?:)
- 这意味着匹配但不捕获;将其排除在外可能会解决那里的大部分问题。
三个规则:
^(\w{2}-\w{2})/questions/(\w+)$
https://regex101.com/r/lI8bQ1/1 - en-us/questions/[single word]
^(\w{2}-\w{2})/questions/(\d+)/.*$
https://regex101.com/r/hV5fK3/1 - en-us/questions/[digits]/discard
^(\w{2}-\w{2})/questions/(\w+)/(\d+)$
https://regex101.com/r/kO0dJ0/1 - en-us/questions/[single
word]/[digits]
将它们全部放入规则集中:
<rule name="en-us questions case one" enabled="true" stopProcessing="true">
<match url="^(\w{2}-\w{2})/questions/(\w+)$" />
<action type="Rewrite" url="/questions.aspx?lang={R:1}&tab={R:2}" />
</rule>
<rule name="en-us questions case two" enabled="true" stopProcessing="true">
<match url="^(\w{2}-\w{2})/questions/(\d+)/.*$" />
<action type="Rewrite" url="/questions.aspx?lang={R:1}&tab={R:2}" />
</rule>
<rule name="en-us questions case three" enabled="true" stopProcessing="true">
<match url="^(\w{2}-\w{2})/questions/(\w+)/(\d+)$" />
<action type="Rewrite" url="/questions.aspx?lang={R:1}&tab={R:2}&pid={R:3}" />
</rule>
* 注意:您可能需要以某种方式调整它,但它应该让您了解如何适应三种不同的变体(如您所见)来重写您的 urls.
这是我的模式:
^(\w{2}-\w{2})/questions(?:/(\w+))?(?:/(\d+))?(?:/.*?)?$
这些是我正在测试的内容:
en-us/questions/ask
en-us/questions/newest/15
en-us/questions/12/just-a-text-to-be-ignored
完美运行,这里是演示:
https://regex101.com/r/yC3tI8/1
但以下重写规则:
<rule name="en-us questions" enabled="true" stopProcessing="true">
<match url="^(\w{2}-\w{2})/questions(?:/(\w+))?(?:/(\d+))?(?:/.*?)?$" />
<action type="Rewrite" url="/questions.aspx?lang={R:1}&tab={R:2}&pid={R:3}" />
</rule>
当我将 link en-us/questions/newest
重定向到:/questions.aspx?lang=en-us&tab=&pid=
这有什么问题吗?现在大约 5 个小时,我只是在复习同样的东西
请注意,您有三个延迟捕获:
(?:/(\w+))?
(?:/(\d+))?
(?:/.*?)?
asp.net's regex implementation 将 ?
解释为:
In addition to specifying that a given pattern may occur exactly 0 or 1 time, the
?
character also forces a pattern or subpattern to match the minimal number of characters when it might match several in an input string.
所以 asp.net 没有为 1 分配任何字符,没有为 2 分配任何字符,并收集其余字符3.
要使用贪婪匹配而不是惰性匹配 ?
强制使用:{0,1}
所以你的正则表达式应该是这样的:
^(\w{2}-\w{2})/questions(?:/(\w+)){0,1}(?:/(\d+)){0,1}(?:/.*?)?$
由于您有三种可能的 url 结局最终会影响重写 url 的结果,您可以设置一个全面的规则 希望 匹配你想要的一切,或者你可以设置三个规则来相应地处理每个规则:
一条规则:
^(\w{2}-\w{2})/questions/(\w+)/?(\d+)?.*$
https://regex101.com/r/dN8bM9/1 - tries to handle all cases
<rule name="en-us questions" enabled="true" stopProcessing="true">
<match url="^(\w{2}-\w{2})/questions/(\w+)/?(\d+)?.*$" />
<action type="Rewrite" url="/questions.aspx?lang={R:1}&tab={R:2}&pid={R:3}" />
</rule>
* 注意:原始模式未能捕获第二组的一个可能原因是包含 (?:)
- 这意味着匹配但不捕获;将其排除在外可能会解决那里的大部分问题。
三个规则:
^(\w{2}-\w{2})/questions/(\w+)$
https://regex101.com/r/lI8bQ1/1 - en-us/questions/[single word]
^(\w{2}-\w{2})/questions/(\d+)/.*$
https://regex101.com/r/hV5fK3/1 - en-us/questions/[digits]/discard
^(\w{2}-\w{2})/questions/(\w+)/(\d+)$
https://regex101.com/r/kO0dJ0/1 - en-us/questions/[single word]/[digits]
将它们全部放入规则集中:
<rule name="en-us questions case one" enabled="true" stopProcessing="true">
<match url="^(\w{2}-\w{2})/questions/(\w+)$" />
<action type="Rewrite" url="/questions.aspx?lang={R:1}&tab={R:2}" />
</rule>
<rule name="en-us questions case two" enabled="true" stopProcessing="true">
<match url="^(\w{2}-\w{2})/questions/(\d+)/.*$" />
<action type="Rewrite" url="/questions.aspx?lang={R:1}&tab={R:2}" />
</rule>
<rule name="en-us questions case three" enabled="true" stopProcessing="true">
<match url="^(\w{2}-\w{2})/questions/(\w+)/(\d+)$" />
<action type="Rewrite" url="/questions.aspx?lang={R:1}&tab={R:2}&pid={R:3}" />
</rule>
* 注意:您可能需要以某种方式调整它,但它应该让您了解如何适应三种不同的变体(如您所见)来重写您的 urls.