tags:

views:

46

answers:

2

Sorry if this has been asked, my search brought up many off topic posts.

I'm trying to convert wildcards from a user defined search string (wildcard is "*") to postgresql like wildcard "%".

I'd like to handle escaping so that "%" => "\%" and "\*" => "*"

I know i could replace \* with something else prior to replacing * and then swap it back, but i'd prefer not to and instead only convert * using a pattern that selects it when not proceeded by \.

String convertWildcard(String like)
{
    like = like.replaceAll("%", "\\%");
    like = like.replaceAll("\\*", "%");
    return like;
}

Assert.assertEquals("%", convertWildcard("*"));
Assert.assertEquals("\\%", convertWildcard("%"));
Assert.assertEquals("*", convertWildcard("\\*")); // FAIL

Assert.assertEquals("a%b", convertWildcard("a*b"));
Assert.assertEquals("a\\%b", convertWildcard("a%b"));
Assert.assertEquals("a*b", convertWildcard("a\\*b")); // FAIL

ideas welcome.

EDIT

to clarify,

i want a method that makes 1 or more String.replaceAll calls to convert a string so that

  • occurances of % become \%,
  • ocurrances of * become % and
  • occurances of \* become *.

the best answer will use the least calls to String.replaceAll.

+1  A: 

You need what is called "Negative Lookbehind". To select all % not preceded by \:

(?<!\\)% (pure regex expression)

to use it in Java you need to add some masking:

string.replaceAll("(?<!\\\\)%", "*");

serg
thanks serg, to fit the question, your answer is `like = like.replaceAll("%", "\\%"); like = like.replaceAll("(?<!\\\\)\\*", "%"); like = like.replaceAll("\\*", "*"); return like;`. looks like a good answer to me. p.
pstanton
actually that last replaceall should be `like = like.replaceAll("\\\\\\*", "*");`
pstanton
+1  A: 

Note also that you aren't escaping your backslashes enough in some of your assert tests. See the section marked "Regular Expressions, Literal Strings and Backslashes" in http://www.regular-expressions.info/java.html

David Gelhar
ah, you're right .. i should have run that before posting eh ;)
pstanton