2
votes

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
Addendum: if there's someone out there who has sufficient rep, you may want to create a "racket" or "racket-scheme" tag. There isn't one yet, and the PLT Scheme guys are trying to change the name of their project.Inaimathi
I added the tag for you.Mark Byers
Is there any particular reason you can't just (map not 'result-of-this-function) to get the negation? Or is this more of an "I would like to understand why this isn't working" question?jakebman
Yes; the particular place I'm using it to initialize the Racket Server. It has a property called "servlet-regexp", which takes a regular expression to determine which URIs to apply dispatch to. If that property could take a function which returned a boolean value instead of a regexp, I would have used the method you suggest.Inaimathi

1 Answers

2
votes

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).)*$"