简体   繁体   中英

Regex.Replace replaces more than bargained for

I'm writing some test cases for IIS Rewrite rules, but my tests are not matching the same way as IIS is, leading to some false negatives.

Can anyone tell me why the following two lines leads to the same result?

Regex.Replace("v1/bids/aedd3675-a0f2-4494-a2c0-32418cf2476a", ".*v[1-9]/bids/.*", "http://localhost:9900/$0")
Regex.Replace("v1/bids/aedd3675-a0f2-4494-a2c0-32418cf2476a", "v[1-9]/bids/", "http://localhost:9900/$0")

Both return:

http://localhost:9900/v1/bids/aedd3675-a0f2-4494-a2c0-32418cf2476a

But I would expect the last regex to return:

http://localhost:9900/v1/bids/

As the GUID is not matched.

On IIS, the pattern tester yields the result below. Is {R:0} not equivalent to $0 ?

What I am asking is:

Given the test input of v[1-9]/bids/ , how can I match IIS' way of doing Regex replaces so that I get the result http://localhost:9900/v1/bids/ , which appears to be what IIS will rewrite to.

IIS正则表达式匹配

The point here is that the pattern you have matches the test strings at the start.

The first .*v[1-9]/bids/.* regex matches 0+ any characters but a newline (as many as possible) up to the last v followed with a digit (other than 0 ) and followed with /bids/ , and then 0+ characters other than a newline. Since the string is matched at the beginning the whole string is matched and placed into Group 0. In the replacement, you just pre-pend http://localhost:9900/ to that value.

The second regex replacement returns the same result because the regex matches v1/bids/ , stores it in Group 0, and replaces it with http://localhost:9900/ + v1/bids/ . What remains is just appended to the replacement result as it does not match.

You need to match that "tail" in order to remove it.

To only get the http://localhost:9900/v1/bids/ , use a capturing group around the v[0-9]/bids/ and use the $1 backreference in the replacement part:

(v[1-9]/bids/).*

Replace with http://localhost:9900/$1 . Result: http://localhost:9900/v1/bids/

See the regex demo

Update

The IIS keeps the base URL and then adds the parts you match with the regex. So, in your case, you have http://localhost:9900/ as the base URL and then you match v1/bids/ with the regex. So, to simulate this behavior, just use Regex.Match :

var rx = Regex.Match("v1/bids/aedd3675-a0f2-4494-a2c0-32418cf2476a", "v[1-9]/bids/");
var res = rx.Success ? string.Format("http://localhost:9900/{0}", rx.Value) : string.Empty;

See the IDEONE demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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