[英]Preventing token injection when replacing substrings
I have a list of key/value strings and a template to replace them in. However, I don't want to replace them twice if one of the values is another token.我有一个键/值字符串列表和一个用于替换它们的模板。但是,如果其中一个值是另一个标记,我不想替换它们两次。 For example:
例如:
tokens: [
Token(Key: "{A}", Value: "{B}"),
Token(Key: "{B}", Value: "b" )
]
template = "Hello, {A}"
>>> replace(template, tokens)
Actual: "b"
Expected: "{B}"
Here's the code:这是代码:
import java.util.regex.*;
class Main {
public static String replace(String template, Token... tokens) {
for ( final Token token : tokens ) {
template = Pattern.compile( token.getKey(), Pattern.LITERAL + Pattern.CASE_INSENSITIVE )
.matcher( template )
.replaceAll( Matcher.quoteReplacement( token.getValue() ) );
}
return template;
}
public static void main(String[] args) {
String result = replace( "Hello, {A}",
new Token("{A}", "{B}"),
new Token("{B}", "b" ) );
System.out.println(result);
}
private static class Token {
String key;
String value;
public Token(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
}
}
This must also work for special characters:这也必须适用于特殊字符:
replace("{A}", new Token("{A}", "$0.00")) -> "$0.00"
The point here is to parse the string with the regex only once , make only one pass and when you match your key pattern, it is just {[^{}]*}
, any substring between {
and }
with no curly braces in between, check if there is a token with this key in your Token
list, and if there is, replace with this token value, else, put the matched text back.这里的要点是只用正则表达式解析字符串一次,只通过一次,当你匹配你的键模式时,它只是
{[^{}]*}
,任何 substring 之间的{
和}
之间没有花括号, 检查你的Token
列表中是否有这个键的 token,如果有,用这个 token 值替换,否则,把匹配的文本放回去。
You may use您可以使用
public static final Pattern keypattern = Pattern.compile("\\{[^{}]*}");
public static Token getTokenByKey(String key, Token... tokens) {
for ( final Token token : tokens ) {
if (token.getKey().toUpperCase().equals(key.toUpperCase()))
return token;
}
return null;
}
public static String replace(String template, Token... tokens) {
Matcher m = keypattern.matcher( template );
StringBuffer sb = new StringBuffer();
while (m.find()) {
Token t = getTokenByKey(m.group(), tokens);
if (t != null) {
m.appendReplacement(sb, Matcher.quoteReplacement(t.getValue()));
} else {
m.appendReplacement(sb, Matcher.quoteReplacement(m.group()));
}
}
m.appendTail(sb);
return sb.toString();
}
The main method code executed like主要方法代码执行如下
public static void main(String[] args) {
String result = replace( "Hello, {A} {c}",
new Token("{A}", "{B}"),
new Token("{B}", "b" ) );
System.out.println(result);
}
will output Hello, {B} {c}
.将 output
Hello, {B} {c}
。
See the Java demo online .在线查看 Java 演示。
The if (token.getKey().toUpperCase().equals(key.toUpperCase()))
line ensures the case insensitive matching. if (token.getKey().toUpperCase().equals(key.toUpperCase()))
行确保不区分大小写的匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.