Найти и заменить регулярное выражение java
Я пытаюсь найти переменные среды во входных данных и заменить их значениями.
Образец переменной env имеет значение ${\\.}
Pattern myPattern = Pattern.compile( "(${\\.})" );
String line ="${env1}sojods${env2}${env3}";
Как заменить env1
на 1
и env2
на 2
и env3
на 3
, поэтому что после этого у меня будет новая строка 1sojods23
?
Ответы
Ответ 1
Строки в Java являются неизменяемыми, что делает это несколько сложным, если вы говорите о произвольном количестве вещей, которые вам нужно найти и заменить.
В частности, вам нужно определить свои замены в Map
, использовать StringBuilder
(до Java 9 следует использовать менее производительный StringBuffer
) и методы appendReplacements()
и appendTail()
из Matcher
. Окончательный результат будет сохранен в вашем StringBuilder
(или StringBuffer
).
Map<String, String> replacements = new HashMap<String, String>() {{
put("${env1}", "1");
put("${env2}", "2");
put("${env3}", "3");
}};
String line ="${env1}sojods${env2}${env3}";
String rx = "(\\$\\{[^}]+\\})";
StringBuilder sb = new StringBuilder(); //use StringBuffer before Java 9
Pattern p = Pattern.compile(rx);
Matcher m = p.matcher(line);
while (m.find())
{
// Avoids throwing a NullPointerException in the case that you
// Don't have a replacement defined in the map for the match
String repString = replacements.get(m.group(1));
if (repString != null)
m.appendReplacement(sb, repString);
}
m.appendTail(sb);
System.out.println(sb.toString());
Выход:
1sojods23
Ответ 2
Я знаю, что это старый, я сам искал пример appendReplacement/appendTail
, когда нашел его; Тем не менее, вопрос OP не нуждается в тех сложных многолинейных решениях, которые я видел здесь.
В этом точном случае, когда заменяемая строка сохраняет значение, которое мы хотим заменить, тогда это можно сделать легко с помощью replaceAll
:
String line ="${env1}sojods${env2}${env3}";
System.out.println( line.replaceAll("\\$\\{env([0-9]+)\\}", "$1") );
// Output => 1sojods23
DEMO
Когда замена случайна на основе некоторых условий или логики для каждого совпадения, вы можете использовать appendReplacement/appendTail
например
Ответ 3
Это дает вам 1sojods23
:
String s = "${env1}sojods${env2}${env3}";
final Pattern myPattern = Pattern.compile("\\$\\{[^\\}]*\\}");
Matcher m = myPattern.matcher(s);
int i = 0;
while (m.find()) {
s = m.replaceFirst(String.valueOf(++i));
m = myPattern.matcher(s);
}
System.out.println(s);
и это тоже работает:
final String re = "\\$\\{[^\\}]*\\}";
String s = "${env1}sojods${env2}${env3}";
int i = 0;
String t;
while (true) {
t = s.replaceFirst(re, String.valueOf(++i));
if (s.equals(t)) {
break;
} else {
s = t;
}
}
System.out.println(s);
Ответ 4
Надеюсь, вы найдете этот код полезным:
Pattern phone = Pattern.compile("\\$\\{env([0-9]+)\\}");
String line ="${env1}sojods${env2}${env3}";
Matcher action = phone.matcher(line);
StringBuffer sb = new StringBuffer(line.length());
while (action.find()) {
String text = action.group(1);
action.appendReplacement(sb, Matcher.quoteReplacement(text));
}
action.appendTail(sb);
System.out.println(sb.toString());
Ожидается выход: 1sojods23
.
Ответ 5
Вы можете использовать StringBuffer в сочетании с методом Matcher appendReplacement(), но если шаблон не соответствует, нет смысла создавать StringBuffer.
Например, вот шаблон, который соответствует ${...}. Группа 1 - это содержимое между фигурными скобками.
static Pattern rxTemplate = Pattern.compile("\\$\\{([^}\\s]+)\\}");
И вот примерная функция, которая использует этот шаблон.
private static String replaceTemplateString(String text) {
StringBuffer sb = null;
Matcher m = rxTemplate.matcher(text);
while (m.find()) {
String t = m.group(1);
t = t.toUpperCase(); // LOOKUP YOUR REPLACEMENT HERE
if (sb == null) {
sb = new StringBuffer(text.length());
}
m.appendReplacement(sb, t);
}
if (sb == null) {
return text;
} else {
m.appendTail(sb);
return sb.toString();
}
}
Ответ 6
Map<String, String> replacements = new HashMap<String, String>() {
{
put("env1", "1");
put("env2", "2");
put("env3", "3");
}
};
String line = "${env1}sojods${env2}${env3}";
String rx = "\\$\\{(.*?)\\}";
StringBuffer sb = new StringBuffer();
Pattern p = Pattern.compile(rx);
Matcher m = p.matcher(line);
while (m.find()) {
// Avoids throwing a NullPointerException in the case that you
// Don't have a replacement defined in the map for the match
String repString = replacements.get(m.group(1));
if (repString != null)
m.appendReplacement(sb, repString);
}
m.appendTail(sb);
System.out.println(sb.toString());
В приведенном выше примере мы можем использовать карту только с ключом и значения --keys могут быть env1, env2..
Ответ 7
Использовать группы после сопоставления ${env1}
будет вашей первой группой, а затем вы будете использовать регулярное выражение для замены того, что находится в каждой группе.
Pattern p = Pattern.compile("(${\\.})");
Matcher m = p.matcher(line);
while (m.find())
for (int j = 0; j <= m.groupCount(); j++)
//here you do replacement - check on the net how to do it;)