我正在尝试为.Net UrlRewriter构建一个正则表达式,我需要将其余的查询字符串与'?'一起附加到新的url字符仅在查询字符串存在时。 一些例子:
/products/product.asp?func=show&id=1
becomes
/product/1.asp
/products/product.asp?func=show&id=1&sid=2&utm_medium=none
becomes
/product/1.asp?sid=2&utm_medium=none
我设法构建了一个表达式,但是我在从查询字符串中追加额外的值时遇到了问题,实际上当没有其他查询字符串值时我不想使用“?”我希望从最后修剪它。
var reg = new Regex(@"^/products/product\.asp\?(?:func=show&)?id=(?<id>\d+)(&(?<tail>.+))?$");
var urls = new []
{
"/products/product.asp?func=show&id=34123&sid=1&bit=2&utm_medium=etc",
"/products/product.asp?func=show&id=34123&sid=1",
"/products/product.asp?func=show&id=34123",
"/products/product.asp?id=34123",
};
urls.Select(url=> reg.Replace(url,"/product/${id}.asp?${tail}"))
.Dump();
此输出
/product/34123.asp?sid=1&bit=2&utm_medium=etc
/product/34123.asp?sid=1
/product/34123.asp?
/product/34123.asp?
我需要修剪'?'来自查询。
不接受像TrimEnd('?')这样的解决方案,因为重写模块使用正则表达式,我不想仅为Trim()调用覆盖它。
表达式 "^/products/product\.asp\?(?:func=show&)?id=(?<id>\d+)(&(?<tail>.+))?$"
表示:
Match any string which starts with "/products/product.asp?"
optionally followed by string "func=show&"
followed by string "id="
followed by at least one digit
optionally followed by the next pattern:
a string which starts with "&"
followed by at least one character
followed by end line
所以问题是如何选择使用“?”这种替代模式中的角色
/product/${id}.asp?${tail}
尾巴附近的。
答案 0 :(得分:2)
如何使用两个正则表达式:一个使用"id=(\d+)$"
而另一个使用"id=(\d+)&(.+)$"
?
一个人不会添加'?',另一个会添加它。
答案 1 :(得分:1)
感谢Chris的建议。我为“?”做了一个lookbehind。仅当“尾部”具有类似“?”的前缀时才匹配“尾部”。跟着是任何角色。原本的 ”?”也被捕获到一个组中,所以我可以在替换中使用它。如果没有“尾部”,则不会捕获前缀定义中的组。
正则表达式是:
^/products/product\.asp\?(?:func=show&)?id=(?<id>\d+)((?<=(?<q>\?).*)&(?<tail>.+))?$
替换是:
"/product/${id}.asp${q}${tail}"
外观是:
(?<=(?<q>\?).*)