正则表达式Java PatternSyntaxException:字符串替换的非法重复?
我正在尝试编写一个方法,该方法将接受一个String
,检查它是否有某些令牌的实例(例如${fizz}
、${buzz}
、${foo}
,等等),并用从Map<String,String>
获取的新字符串替换每个令牌
例如,如果我将以下字符串传递给此方法:
"How now ${fizz} cow. The ${buzz} had oddly-shaped ${foo}."
如果该方法参考了以下Map<String,String>
:
Key Value
==========================
"fizz" "brown"
"buzz" "arsonist"
"foo" "feet"
那么结果字符串将是:
"How now brown cow. The arsonist had oddly-shaped feet."
以下是我的方法:
String substituteAllTokens(Map<String,String> tokensMap, String toInspect) {
String regex = "\\$\\{([^}]*)\\}";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(toInspect);
while(matcher.find()) {
String token = matcher.group(); // Ex: ${fizz}
String tokenKey = matcher.group(1); // Ex: fizz
String replacementValue = null;
if(tokensMap.containsKey(tokenKey))
replacementValue = tokensMap.get(tokenKey);
else
throw new RuntimeException("String contained an unsupported token.");
toInspect = toInspect.replaceFirst(token, replacementValue);
}
return toInspect;
}
运行此操作时,会出现以下异常:
Exception in thread "main" java.util.regex.PatternSyntaxException: Illegal repetition near index 0
${fizz}
^
at java.util.regex.Pattern.error(Pattern.java:1730)
at java.util.regex.Pattern.closure(Pattern.java:2792)
at java.util.regex.Pattern.sequence(Pattern.java:1906)
at java.util.regex.Pattern.expr(Pattern.java:1769)
at java.util.regex.Pattern.compile(Pattern.java:1477)
at java.util.regex.Pattern.<init>(Pattern.java:1150)
at java.util.regex.Pattern.compile(Pattern.java:840)
at java.lang.String.replaceFirst(String.java:2158)
...rest of stack trace omitted for brevity (but available upon request!)
我为什么会得到这个?正确的解决方法是什么提前谢谢
# 1 楼答案
正如Patashu所指出的,问题在于
replaceFirst(token, replacementValue)
,它要求在第一个参数中使用正则表达式,而不是文本。将其更改为replaceFirst(Pattern.quote(token), replacementValue)
,您会做得很好我还对第一个正则表达式做了一些修改,因为它使用
+
而不是*
更快,但这不是必需的# 2 楼答案
你可以让你的正则表达式有点难看,但是 这会奏效的
# 3 楼答案
改编自
Matcher.replaceAll
# 4 楼答案
在
${fizz}
{
是正则表达式引擎的一个指示器,表示您将要启动一个重复指示器,如{2,4}
,它表示“前一个标记的2到4倍”。但是{f
是非法的,因为它后面必须跟一个数字,所以它抛出一个异常您需要转义所有正则表达式元字符(在本例中为
$
、{
和}
)(尝试使用http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html#quote(java.lang.String))或使用不同的方法以字符串代替字符串,而不是以正则表达式代替字符串# 5 楼答案
使用字符串replaceAll。 用于测试的示例输入字符串 “会话键1”:
,