1

I am a bit new to Java, so I am just unsure if I am doing things like they should or not. I am developing a Program, that is more for learning Java purpose and which is thought for commandline use. One of the Features should be a kind of search an replace.

Starting the program from the commandline like this:

java -jar pro.jar -s ${ftp://www.stuff.com} -r foo

means: search for the exact String ${ftp://www.stuff.com} and replace it with foo. I want to search with an Regexp, so I have to escape the escape-characters ($,(,{,},\,…) in the search string.

${ftp://www.stuff.com} --> \$\{ftp:\/\/www\.stuff\.com\}

Therefore I wrote that function:

private static Pattern getSearchPattern()
{
    String searchArg = cli.getOptionValue( "s" ).trim();
    StringBuffer escapedSearch = new StringBuffer();
    Pattern metas = Pattern.compile( "([\\.\\?\\*\\{\\}\\[\\]\\(\\)\\^\\$\\+\\|\\\\])" );
    Matcher metaMatcher = metas.matcher( searchArg );

    while( metaMatcher.find() )
    {
        metaMatcher.appendReplacement(escapedSearch, "\\\\\\\\$0" );
    }
    metaMatcher.appendTail( escapedSearch );

    return Pattern.compile( escapedSearch.toString() );
}

all in all does this work, but there are so many backslashes. Does this escape all metachrackters? Is that a »robust« solution?

1
  • dont know if its a possibility for you but maybe you could make sure there's just a single argument that accepts patterns and provide it always as the last one. then the remainder ofthe commandline is always your argument and there's less escaping to do Commented May 4, 2013 at 9:20

1 Answer 1

6

You can do something much better than use them. You can use a PatternQuote.

Pattern metas = Pattern.quote("no escaped regex chars in here");

One other way to get rid of \\ is to use character classes []. So if you put [.] instead of \\. the results will be the same and hopefully you get some readability.

Sign up to request clarification or add additional context in comments.

2 Comments

+1 for Pattern.quote, which is designed for precisely this task. There's also Matcher.quoteReplacement which you can use on the replacement string if you want it to be treated literally (rather than $1 being treated as a backreference to a capturing group in the pattern).
Thank you! Works just like expected! Nice!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.