регулярное выражение Java найти и заменить - PullRequest
10 голосов
/ 07 марта 2012

Я пытаюсь найти переменные среды на входе и заменить их значениями.

Шаблон переменной env: ${\\.}

Pattern myPattern = Pattern.compile( "(${\\.})" );
String line ="${env1}sojods${env2}${env3}";

Как я могу заменить env1 на 1 и env2 на 2 и env3 на 3, поэтому что после этого у меня будет новая строка 1sojods23?

Ответы [ 7 ]

42 голосов
/ 07 марта 2012

Строки в Java неизменны, что делает это несколько сложным, если вы говорите о произвольном количестве вещей, которые вам нужно найти и заменить.

В частности, вам необходимо определить замены в Map, использовать методы StringBuffer и appendReplacements() и appendTail() из Matcher. Окончательный результат будет сохранен в вашем 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 = "(\\$\\{[^}]+\\})";

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

Выход:

1sojods23
8 голосов
/ 28 января 2016

Я знаю, что это старый, я сам искал, appendReplacement/appendTail пример, когда я его нашел;Однако вопрос ОП не нуждается в тех сложных многострочных решениях, которые я видел здесь.

В этом конкретном случае, когда строка для замены содержит значение, которое мы хотим заменить, тогда это можно сделатьлегко с replaceAll:

String line ="${env1}sojods${env2}${env3}";

System.out.println( line.replaceAll("\\$\\{env([0-9]+)\\}", "$1") );

// Output => 1sojods23

DEMO

Когда замена является случайной на основе некоторых условий или логики в каждом совпадении,Вы можете использовать appendReplacement/appendTail например

3 голосов
/ 07 марта 2012

Это дает вам 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);
2 голосов
/ 07 марта 2012

Надеюсь, вы найдете этот код полезным:

    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.

0 голосов
/ 24 апреля 2019
    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());

В приведенном выше примере мы можем использовать карту только с ключом и значениями - ключи могут быть env1, env2 ..

0 голосов
/ 07 марта 2018

Вы можете использовать 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();
    }
}
0 голосов
/ 07 марта 2012

Используйте группы, как только они найдены ${env1} будет вашей первой группой, а затем вы используете регулярное выражение для замены того, что находится в каждой группе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...