Java строка заменяет шаблон регулярного выражения на оцененный ключ - PullRequest
1 голос
/ 16 января 2020

У меня есть строка ввода, подобная этой

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

Значения для {мест} и {вещей} вычисляются лениво (т.е. сначала я выясняю, какими должны быть все ключи заменить и затем вычислить значения для них, а затем заменить их в исходной строке).

Я могу найти все ключи и удалить их, используя приведенный ниже код.

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

, потому что это означает всякий раз, когда я меняю свое регулярное выражение, мне придется обновлять эту логику c. Есть ли более элегантное решение этой проблемы.


вход привет {мир} из {здесь}

вывод привет новый мир из newhere


ввод Я хочу go в {места}, где {вещи} происходят.

вывод Я хочу go в новые места, где происходит что-то новое.

Ответы [ 2 ]

1 голос
/ 16 января 2020

Вы должны использовать API Matcher#appendReplacement и Matcher#appendTail здесь:

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.
0 голосов
/ 16 января 2020

Мы можем использовать 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...