views:

207

answers:

1

I'm trying to create a regex that matches the inverse of a certain string type (so, strings not ending in ".js", for example).

According to the documentation, that should be the expression #rx"(?!\\.js$)", but it doesn't seem to work. To test it out, I have this function:

(define (match-test regex)
    (map (lambda (text)
           (regexp-match? regex text))
         '("foo.js" "bar.css" "baz.html" "mumble.gif" "foobar")))

(match-test #rx"\\.js$") returns (#t #f #f #f #f) as expected, but (match-test #rx"(?!\\.js$)") returns (#t #t #t #t #t), where I would expect (#f #t #t #t #t).

What am I doing wrong, and how do I actually get a regex in Racket to express the idea "match anything which does not contain [x]"?

+1  A: 

You need to anchor the negative match because otherwise it can successfully match (or successfully not match if you like) anywhere in the string. You can anchor the regular expression to the end of the string and use a negative lookbehind to check the last few character. I'm not familiar with the Scheme syntax, but I would imagine that you can use this:

#rx"(?<!\\.js)$"

and how do I actually get a regex in Racket to express the idea "match anything which does not contain [x]"

This is a bit trickier. You can use a negative lookahead for every character in your string. Here is how to match a string not containing foo anywhere. Again apologies if this doesn't quite work in Scheme, but it should demonstrate the idea:

#rx"^((?!foo).)*$"
Mark Byers