简体   繁体   English

iis url-rewrite 中奇怪的正则表达式错误

[英]Weird regex bug in iis url-rewrite

This is my pattern:这是我的模式:

^(\w{2}-\w{2})/questions(?:/(\w+))?(?:/(\d+))?(?:/.*?)?$

these are the what I'm testing:这些是我正在测试的内容:

en-us/questions/ask
en-us/questions/newest/15
en-us/questions/12/just-a-text-to-be-ignored

It works perfectly, here is the demo:它完美运行,这是演示:

https://regex101.com/r/yC3tI8/1 https://regex101.com/r/yC3tI8/1

but the following rewrite rule:但以下重写规则:

<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}&amp;tab={R:2}&amp;pid={R:3}" />
</rule>  

when I give the link en-us/questions/newest redirects to: /questions.aspx?lang=en-us&tab=&pid=当我将链接en-us/questions/newest重定向到: /questions.aspx?lang=en-us&tab=&pid= en-us/questions/newest /questions.aspx?lang=en-us&tab=&pid=

What is wrong with this?这有什么问题? Its now about 5 hours I'm just reviewing the same things现在大约 5 个小时,我只是在回顾同样的事情

Since you have three different possible url endings that ultimately effect the outcome of the rewritten url you can either setup one all inclusive rule that will hopefully match everything you want, or you could setup three rules to handle each accordingly:由于您有三种不同的可能 url 结尾,最终会影响重写 url 的结果,您可以设置一个全包规则,希望能匹配您想要的所有内容,或者您​​可以设置三个规则来相应地处理每个:

One Rule:一条规则:

^(\w{2}-\w{2})/questions/(\w+)/?(\d+)?.*$

https://regex101.com/r/dN8bM9/1 - tries to handle all cases https://regex101.com/r/dN8bM9/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}&amp;tab={R:2}&amp;pid={R:3}" />
</rule> 

* note: one possible reason the original pattern was failing to capture the second group was the inclusion of (?:) - which means match but don't capture; * 注意:原始模式未能捕获第二组的一个可能原因是包含(?:) - 这意味着匹配但不捕获; leaving that out might solve most of the issues there.忽略这一点可能会解决那里的大部分问题。

Three Rules:三个规则:

^(\w{2}-\w{2})/questions/(\w+)$

https://regex101.com/r/lI8bQ1/1 - en-us/questions/[single word] https://regex101.com/r/lI8bQ1/1 - en-us/questions/[单字]

^(\w{2}-\w{2})/questions/(\d+)/.*$

https://regex101.com/r/hV5fK3/1 - en-us/questions/[digits]/discard 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] https://regex101.com/r/kO0dJ0/1 - en-us/questions/[单字]/[数字]

Putting it all together into a ruleset:将所有这些放在一个规则集中:

<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}&amp;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}&amp;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}&amp;tab={R:2}&amp;pid={R:3}" />
</rule>

* note: you might need to adjust this in some way, but it should give you an idea of how to accomodate three different variations (as you seem to have) for rewriting your urls. * 注意:您可能需要以某种方式进行调整,但它应该让您了解如何适应三种不同的变体(如您所见)以重写您的网址。

Note you have three lazy captures:请注意,您有三个懒惰的捕获:

  1. (?:/(\\w+))?
  2. (?:/(\\d+))?
  3. (?:/.*?)?

asp.net's regex implementation interprets ? asp.net 的正则表达式实现解释? as:作为:

In addition to specifying that a given pattern may occur exactly 0 or 1 time, the ?除了指定给定模式可能恰好出现 0 次或 1 次之外, ? character also forces a pattern or subpattern to match the minimal number of characters when it might match several in an input string.当它可能匹配输入字符串中的多个字符时,字符还会强制模式或子模式匹配最少数量的字符。

So asp.net is assigning no characters to 1 , no characters to 2 , and collecting the rest of the characters 3 .因此,asp.net 没有将字符分配给1 ,没有字符分配给2 ,并收集其余的字符3

To use greedy matching instead of the lazy matching ?使用贪婪匹配而不是惰性匹配? forces use: {0,1}强制使用: {0,1}

So you're regex should look like:所以你的正则表达式应该是这样的:

^(\w{2}-\w{2})/questions(?:/(\w+)){0,1}(?:/(\d+)){0,1}(?:/.*?)?$

Live example活生生的例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM