繁体   English   中英

Java字符串用评估的键替换正则表达式模式

[英]Java string replace regex pattern with evaluated key

我有一个像这样的输入字符串

I want to go to {places} where {things} are happening.

{places} 和 {things} 的值是惰性计算的(即首先我找出所有需要替换的键,然后计算它们的值,然后将它们替换为原始字符串)。

我能够找出所有的键并使用下面的代码删除它们。

public class Temp {
    private static final Pattern betweenCurlyBracesMatcher = Pattern.compile("\\{(.*?)\\}");

    public static void main(String args[]) {
        System.out.println(resolve2("hello {world} from {here}"));
    }

    public static String resolve2(String input) {
        Map<String, String> keyValueMap = new HashMap<>();
        Matcher matcher = betweenCurlyBracesMatcher.matcher(input);
        while (matcher.find()) {
            String key = matcher.group(1);
            if (!keyValueMap.containsKey(key)) {
                keyValueMap.put(key, computeValueForKey(key));
            }
        }
        for (Map.Entry<String, String> entry : keyValueMap.entrySet()) {
            input = input.replace("{" + entry.getKey() + "}", entry.getValue());  // << ugly code here
        }
        return input;
    }

    private static String computeValueForKey(String key) {
        return "new" + key;
    }
}

但我不满意

input = input.replace("{" + entry.getKey() + "}", entry.getValue());

因为这意味着每当我更改正则表达式时,我都必须更新此逻辑。 这个问题有没有更优雅的解决方案。


从 {here}输入hello {world}

从某个地方输出hello newworld


输入我想去 {places} 发生 {things} 的地方。

输出我想去新地方发生新事物。

您应该在此处使用Matcher#appendReplacementMatcher#appendTail API:

Map<String, String> keyValueMap = new HashMap<>();
keyValueMap.put("places", "to America");
keyValueMap.put("things", "events");
String input = "I want to go to {places} where {things} are happening.";
Pattern pattern = Pattern.compile("\\{(.*?)\\}");
Matcher matcher = pattern.matcher(input);
StringBuffer buffer = new StringBuffer();

while(matcher.find()) {
    matcher.appendReplacement(buffer, keyValueMap.get(matcher.group(1)));
}
matcher.appendTail(buffer);
System.out.println(buffer.toString());

这打印:

I want to go to to America where events are happening.

我们可以使用 matcher.group(0) 返回整个匹配的字符串

public class Temp {
    private static final Pattern betweenCurlyBracesMatcher = Pattern.compile("\\{(.*?)\\}");

    public static void main(String args[]) {
        System.out.println(resolve2("hello {world} from {here}"));
    }

    public static String resolve2(String input) {
        Map<String, String> keyValueMap = new HashMap<>();
        Matcher matcher = betweenCurlyBracesMatcher.matcher(input);
        while (matcher.find()) {
            String keyBetweenBraces = matcher.group(1);
            String keyWithBraces = matcher.group(0);
            if (!keyValueMap.containsKey(keyWithBraces)) {
                keyValueMap.put(keyWithBraces, computeValueForKey(keyBetweenBraces));
            }
        }
        for (Map.Entry<String, String> entry : keyValueMap.entrySet()) {
            input = input.replace(entry.getKey(), entry.getValue());
        }
        return input;
    }

    private static String computeValueForKey(String key) {
        return "new" + key;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM