Заполнители ошибочно заменены на % char

Я хочу изменить заполнитель в строке, разделенной символом %. Например, %test% следует заменить на SERVER (в примере здесь). В других случаях это будет похоже на %name%, измененное именем пользователя.

Сложность заключается в том, что другие % не являются заполнителями. Кроме того, до его использования неизвестны заполнители. Итак, нам нужно попробовать проверить каждый заполнитель, чтобы определить, является ли он действительным, или оставить %.

Пример строки:

abc %some%%test% efz %other% fref%

Мой полный код:

public class Main {

    public static void main(String[] args) throws Exception {
        String base = "abc %some%%test% efz %other% fref%"; // here is my line

        String completeLine = ""; // the result
        String[] parts = base.split("\\%"); // split by separator
        for(int i = 0; i < parts.length; i++) { // for each parts
            String param = parts[i];
            String placeholder = placeholder(param); // change placeholder
            completeLine += placeholder;
            if (placeholder == param && i > 0) { // if not placeholder and not first %
                completeLine += "%";
            }
        }
        System.out.println(completeLine);
    }
    
    private static String placeholder(String param) {
        if (param.equalsIgnoreCase("test"))
            return "SERVER";
        return param;
    }
}

Фактический результат:

abc some%%SERVER efz %other% fref%

Ожидаемый результат:

abc %some%SERVER efz %other% fref%

Как я могу это сделать?

Что касается if (placeholder == param..., см. Как сравнивать строки в Java?. В любом случае рассмотрите возможность требовать от предоставленных данных всегда экранировать % другим %. Поэтому, когда вы ищете %non-percentage% и находите %%, non-percentage пуст. В этом случае замените его на одинарный %. В противном случае замените этот заполнитель значением, соответствующим non-percentage.

Pshemo 02.09.2024 22:54

Просто пришла мысль. Сколько у вас заполнителей? Возможно, проще просто попытаться заменить их перебором, а не искать те, которые существуют в строке. Конечно, большое количество заполнителей и/или очень длинных строк будут повторяющимися и, следовательно, неэффективными.

WJS 03.09.2024 16:02

@WJS Я могу иметь бесконечный. На самом деле есть что-то вроде %x_1_y%, которое будет искать в базе данных «x» первого пользователя в статистике «y». Итак, по крайней мере, я могу знать, что префикс, начинающийся с «x», может быть заполнителем, но я не могу знать их все.

Elikill58 03.09.2024 16:21
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
3
104
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

  • Ваша логика должна быть на «%test%», а не на «%».
  • Вы можете напрямую использовать замену строки вместо разделения.
String base = "abc %some%%test% efz %other% fref%";

base = base.replaceAll("%test%", "SERVER");

System.out.println(base);
replaceAll буду использовать регулярное выражение (а это не то, что мне нужно), и у меня проблема: я не знаю заполнителей перед его применением, поэтому я вызываю другой метод placeholder здесь
Elikill58 02.09.2024 23:36

@sanurah Вы не используете функции регулярных выражений, поэтому нет смысла звонить replaceAll сюда - используйте replace для того же результата.

DuncG 03.09.2024 10:19

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

DuncG 03.09.2024 10:21

Да, но здесь это не регулярное выражение. Ответ WJS кажется правильным

Elikill58 03.09.2024 10:48

Это все еще возможно с помощью replaceAll, просто в другом варианте.

Pattern pattern = Pattern.compile("\\%([a-zA-Z]*)\\%");

String completeLine = pattern.matcher(base)
  .replaceAll(matchResult -> placeholder(matchResult.group(1)));

Хм... это удаляет % для %test%, а не для %some%?

Stephen C 03.09.2024 01:56

Он удалит % для всех вхождений, а также для %some%.

Rob Spoor 03.09.2024 10:49

Чтобы это исправить, вам понадобится метод placeholder, который принимает как matchResult.group(1) (например, test), так и matchResult.group() (например, %test%). Альтернативно используйте только matchResult.group() и включите % в соответствие, как в ответе WJS.

Rob Spoor 03.09.2024 10:52
Ответ принят как подходящий

Вы также можете сделать следующее:

String base = "abc %some%%test% efz %other% fref%";
Matcher m = Pattern.compile("%.*?%").matcher(base);
String completeLine= base;
while (m.find())  {
     completeLine = completeLine.replace(m.group(), placeholder(m.group()));
}
System.out.println(completeLine);

private static Map<String,String> map = Map.of("%test%", "SERVER", "%other%", "OTHER");
private static String placeholder(String param) {
    return map.getOrDefault(param, param);
}

принты

abc %some%SERVER efz OTHER fref%

Модификация метода заполнителя — это просто предложение использовать карту для хранения сопоставлений placeholder и replacement. Если сопоставление не найдено, возвращается исходный заполнитель.

Другие вопросы по теме