views:

4194

answers:

4

I need to test a url that it does not end with .asp

So test, test.html and test.aspx should match, but test.asp should not match.

Normally you'd test if the url does end with .asp and negate the fact that it matched using the NOT operator in code:

if(!regex.IsMatch(url)) { // Do something }

In that case the regular expression would be \.asp$ but in this case I need the regular expression to result in a match.

Thank you!


Background: I need to use the regular expression as a route contraint in the ASP.NET MVC RouteCollection.MapRoute extension method. The route needs to match all controllers but it should fall through when the controller in the url ends with .asp

+2  A: 

Try this

^((?!\.asp$).)*$
Winston Smith
This works, but is inefficient. There's no need to check at every position that .asp$ cannot be matched. We only need to do the check at the end.
Jan Goyvaerts
Works as well, I gave the answer to Jan for being more efficient. Thanks!
michielvoo
+22  A: 

The trick is to use negative lookbehind.

If you need just a yes/no answer:

(?<!\.asp)$

If you need to match the whole URL:

^.*(?<!\.asp)$

These regexes will work with any URL where the file name occurs at the end of the URL (i.e. URLs without a query or fragment). I'm assuming your URLs fit this limitation given the regex .asp$ in your question. If you want it to work with all URLs, try this:

^[^#?]+(?<!\.asp)([#?]|$)

Or this if you want the regex to match the whole URL:

^[^#?]+(?<!\.asp)([#?].+|$)
Jan Goyvaerts
The second did the trick it seems, I need to do some tests with more urls, but my first unit tests passes now, so thanks!
michielvoo
+1 for good info. Tiny nit pick: the question title notes "1+ characters" and I believe your first two regexes would match empty strings.
Mattias Andersson
In the context of ASP.NET MVC routing constraints, the URL is inspected in pieces: {controller}/{action}/{id}The regex should match the {controller} part, so 'the end' would not always be the end of the url, but the end of the {controller} part of the end.
michielvoo
A: 

Isn't it possible to use something not regex-related like?

string thepath="test.asp";

    if(System.IO.Path.GetExtension(thepath)!=".asp")

    {
    ...........
    }
netadictos
It needs to be a regex and it needs to match.
michielvoo
+3  A: 

Not a regexp, but c# String.EndsWith method which could easily do the job.

ie

string test1 = "me.asp" ;
string test2 = "me.aspx" ;

test1.EndsWith(".asp") // true;
test2.EndsWith(".asp") // false ;
DrG
+1 for not thinking too complicated ;-)
Treb
Nope, -1 for not being a regular expression, sorry to be so strict ;-)
michielvoo
+1 for non complicated solution
Learning
@learning: the answer should be a regular expression.
michielvoo