如何在找到匹配项时将字符串附加到匹配项的左侧?

时间:2011-12-21 15:41:44

标签: .net regex

我正在尝试为.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}
尾巴附近的

2 个答案:

答案 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>\?).*)