3

I am using Java8 and would like to use the following Regex to filter an address from a string, but I get this error:

Error

Exception in thread "main" java.util.regex.PatternSyntaxException: Illegal repetition near index 18
(\d+\s*(\w+ ){1,2}${(?i)\b(street|st|road|rd|avenue|ave|drive|dr|loop|court|ct|circle|cir|lane|ln|boulevard|blvd|way)\.?\b}(\s+${(?i)\b(apt|bldg|dept|fl|hngr|lot|pier|rm|ste|slip|trlr|unit|#)\.? *[a-z0-9-]+\b})?)|(${/P\.? ?O\.? *Box +\d+})
                  ^

Code

private static final String REGEX_ROAD = "(?i)\\b(street|st|road|rd|avenue|ave|drive|dr|loop|court|ct|circle|cir|lane|ln|boulevard|blvd|way)\\.?\\b";
private static final String REGEX_APT = "(?i)\\b(apt|bldg|dept|fl|hngr|lot|pier|rm|ste|slip|trlr|unit|#)\\.? *[a-z0-9-]+\\b";
private static final String REGEX_POBOX = "/P\\.? ?O\\.? *Box +\\d+";

private static final String REGEX_STREET = "(\\d+\\s*(\\w+ ){1,2}${"+REGEX_ROAD+"}(\\s+${"+REGEX_APT+"})?)|(${"+REGEX_POBOX+"})";

    input = input.replaceAll(REGEX_STREET, "<ADDRESS>");

Any help appreciated.

Entire Class:

package com.jobs.spring.service.replace;

public class ReplaceServiceImpl implements ReplaceService {

    private static final String REGEX_ROAD = "(?i)\\b(street|st|road|rd|avenue|ave|drive|dr|loop|court|ct|circle|cir|lane|ln|boulevard|blvd|way)\\.?\\b";
    private static final String REGEX_APT = "(?i)\\b(apt|bldg|dept|fl|hngr|lot|pier|rm|ste|slip|trlr|unit|#)\\.? *[a-z0-9-]+\\b";
    private static final String REGEX_POBOX = "/P\\.? ?O\\.? *Box +\\d+";

    private static final String REGEX_STREET = "(\\d+\\s*(\\w+ ){1,2}${"+REGEX_ROAD+"}(\\s+${"+REGEX_APT+"})?)|(${"+REGEX_POBOX+"})";

    @Override
    public String removePII(String input) {
        input = input.replaceAll(REGEX_STREET, "<ADDRESS>");
        return input;
    }

    public static void main(String[] args) {
        ReplaceService rep = new ReplaceServiceImpl();
        System.out.println(rep.removePII("1234 Flex Road and 21 happy street"));
    }
}
4
  • 6
    Remove ${ and the next } after it, that is enough to build a pattern dynamically. Commented May 18, 2017 at 10:36
  • Thanks again Wiktor Stribiżew, that works. Commented May 18, 2017 at 10:38
  • Why don't you appreciate the effort others put in your question and accept the answer? Commented May 18, 2017 at 10:52
  • It doesn't allow me to accept the answer for the first 10 minutes. Commented May 18, 2017 at 10:54

1 Answer 1

9

Java does not support string interpolation, the ${...} JavaScript-like template literal placeholders are not supported and are treated as literal symbols.

Since $ means the end of a string and is a zero-width assertion, it should not be quantified. However, Java regex engine is lenient to the user and allows the usage of a quantifier with a zero-width assertion (you may use ${5} although it makes no sense, there can only be a single end of a string at a given position).

The major problem here is that { (start of a limiting quantifier) must be followed with a number denoting the number of repetitions and if there is a symbol other than a digit, anything but a number followed with } or ,MAX_REPEATITION_VALUE}, the Illegal repetition error will show up.

So, just remove ${ and }.

String REGEX_STREET = "(\\d+\\s*(\\w+ ){1,2}"+REGEX_ROAD+"(\\s+"+REGEX_APT+")?)|("+REGEX_POBOX+")";

See the Java demo.

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

Comments

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.