tags:

views:

1345

answers:

6

Hi all,

I would like to match everything but *.xhtml. I have a servlet listening to *.xhtml and I want another servlet to catch everything else. If I map the Faces Servlet to everything (*), it bombs out when handling icons, stylesheets, and everything that is not a faces request.

This is what I've been trying unsuccessfully.

Pattern inverseFacesUrlPattern = Pattern.compile(".*(^(\\.xhtml))");

Any ideas?

Thanks,

Walter

+3  A: 

What you need is a negative lookbehind (java example).

String regex = ".*(?<!\\.xhtml)$";
Pattern pattern = Pattern.compile(regex);

This pattern matches anything that doesn't end with ".xhtml".

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NegativeLookbehindExample {
  public static void main(String args[]) throws Exception {
    String regex = ".*(?<!\\.xhtml)$";
    Pattern pattern = Pattern.compile(regex);

    String[] examples = { 
      "example.dot",
      "example.xhtml",
      "example.xhtml.thingy"
    };

    for (String ex : examples) {
      Matcher matcher = pattern.matcher(ex);
      System.out.println("\""+ ex + "\" is " + (matcher.find() ? "" : "NOT ") + "a match.");
    }
  }
}

so:

% javac NegativeLookbehindExample.java && java NegativeLookbehindExample                                                                                                                                        
"example.dot" is a match.
"example.xhtml" is NOT a match.
"example.xhtml.thingy" is a match.
rampion
Unfortunately, this doesn't work (tested to confirm it); probably because the negative look-ahead assertion needs something else to look-ahead of!
Siddhartha Reddy
OK, by the time I posted the above comment, the answer was edited to a negative look-behind assertion. But this doesn't work either.
Siddhartha Reddy
Sure it does - try the sample code.
rampion
Yes, lookbehind from $ is the proper solution. I can see now :-)
Vinko Vrsalovic
Walter said in his self-reply that the regex has to match the whole string, as if matches() were being used instead of find(). Just tack a .* onto the front of that regex and you've got the best answer.
Alan Moore
+4  A: 

Not regular expresion, but why use that when you don't have to?

String page = "blah.xhtml";

if( page.endsWith( ".xhtml" ))
{
 // is a .xhtml page match
}
Martlark
A: 

You could use the negative look-ahead assertion:

Pattern inverseFacesUrlPattern = Pattern.compile("^.*\\.(?!xhtml).*$");

Please note that the above only matches if the input contains an extension (.something).

Siddhartha Reddy
This will also flunk "an.xhtml.example.document.txt"
rampion
A: 

Hi all,

This pattern is going directly inside of a Servlet Filter configuration, so it must either be a regular expression or a tomcat expression. The regular expression is the only one that will work.

Siddhartha Reddy, your regex appears to work when using matcher.matches() which is what the SeamFilter will be using, so that should do it.

Those are good ideas, I will give them a try later.

Thanks,

Walter

@Walter: you should edit your question to include this information (rather than putting it in an answer, since it's not a proposed answer). It's the way things are done around here. Thanks for the question!
rampion
A: 

Hi,

I created this thread without logging in, so it isn't mapped back to me :(.

To summarize what I'm trying to do again ...

I want to match everything exception *.xhtml.

So, that would be *.ico, *.jpeg, *.png, *.css, *.js, *.html, etc.

In other terms the intersection of * - *.xhtml.

Walter

A: 

You're really only missing a "$" at the end of your pattern and a propper negative look-behind (that "(^())" isn't doing that). Look at the special constructs part of the syntax.

The correct pattern would be:

.*(?<!\.xhtml)$
  ^^^^-------^ This is a negative look-behind group.

A Regular Expression testing tool is invaluable in these situations when you normally would rely on people to double check your expressions for you. Instead of writing your own please use something like RegexBuddy on Windows or Reggy on Mac OS X. These tools have settings allowing you to choose Java's regular expression engine (or a work-alike) for testing. If you need to test .NET expressions try Expresso. Also, you could just use Sun's test-harness from their tutorials, but it's not as instructive for forming new expressions.

dlamblin