Я хочу изменить заполнитель в строке, разделенной символом %
. Например, %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%
Как я могу это сделать?
Просто пришла мысль. Сколько у вас заполнителей? Возможно, проще просто попытаться заменить их перебором, а не искать те, которые существуют в строке. Конечно, большое количество заполнителей и/или очень длинных строк будут повторяющимися и, следовательно, неэффективными.
@WJS Я могу иметь бесконечный. На самом деле есть что-то вроде %x_1_y%
, которое будет искать в базе данных «x» первого пользователя в статистике «y». Итак, по крайней мере, я могу знать, что префикс, начинающийся с «x», может быть заполнителем, но я не могу знать их все.
String base = "abc %some%%test% efz %other% fref%";
base = base.replaceAll("%test%", "SERVER");
System.out.println(base);
replaceAll
буду использовать регулярное выражение (а это не то, что мне нужно), и у меня проблема: я не знаю заполнителей перед его применением, поэтому я вызываю другой метод placeholder
здесь
@sanurah Вы не используете функции регулярных выражений, поэтому нет смысла звонить replaceAll
сюда - используйте replace
для того же результата.
@Elikill58 Elikill58 Использование регулярных выражений является очевидным решением вашей проблемы, поэтому вы сопоставляете % вокруг того, что выглядит как переменные среды. Если вы не можете использовать решение с регулярным выражением, лучше всего добавить объяснение в вопрос, чтобы не тратить время других людей.
Да, но здесь это не регулярное выражение. Ответ WJS кажется правильным
Это все еще возможно с помощью replaceAll, просто в другом варианте.
Pattern pattern = Pattern.compile("\\%([a-zA-Z]*)\\%");
String completeLine = pattern.matcher(base)
.replaceAll(matchResult -> placeholder(matchResult.group(1)));
Хм... это удаляет % для %test%
, а не для %some%
?
Он удалит % для всех вхождений, а также для %some%
.
Чтобы это исправить, вам понадобится метод placeholder
, который принимает как matchResult.group(1)
(например, test
), так и matchResult.group()
(например, %test%
). Альтернативно используйте только matchResult.group()
и включите % в соответствие, как в ответе WJS.
Вы также можете сделать следующее:
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
. Если сопоставление не найдено, возвращается исходный заполнитель.
Что касается
if (placeholder == param...
, см. Как сравнивать строки в Java?. В любом случае рассмотрите возможность требовать от предоставленных данных всегда экранировать%
другим%
. Поэтому, когда вы ищете%non-percentage%
и находите%%
,non-percentage
пуст. В этом случае замените его на одинарный%
. В противном случае замените этот заполнитель значением, соответствующимnon-percentage
.