java.util.regex.PatternSyntaxException:索引附近非法重复

时间:2017-05-18 10:35:00

标签: java regex

我正在使用Java8,并希望使用以下Regex从字符串中过滤地址,但是我收到此错误:

错误

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+})
                  ^

代码

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>");

任何帮助表示感谢。

全班:

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"));
    }
}

1 个答案:

答案 0 :(得分:6)

Java不支持字符串插值,不支持${...}类似JavaScript的模板文字占位符,并将其视为文字符号。

由于$表示字符串的结尾并且是零宽度断言,因此不应对其进行量化。但是,Java正则表达式引擎对用户来说是宽松的,允许使用具有零宽度断言的量词(你may use ${5}虽然没有意义,但在给定位置只能有一个字符串的一端)。

这里的主要问题是{(限制量词的开始)必须跟一个表示重复次数的数字,如果有一个数字而不是一个数字,除了一个数字后面跟着{ {1}}或}非法重复错误将会显示。

因此,只需删除,MAX_REPEATITION_VALUE}${

}

请参阅Java demo