java正则表达式查找和替换

时间:2021-08-12 23:36:06

I am trying to find environment variables in input and replace them with values.

我试图在输入中找到环境变量并用值替换它们。

The pattern of env variable is ${\\.}

env变量的模式是$ {\\。}

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

How can I replace env1 with 1 and env2 with 2 and env3 with 3, so that after this I will have a new string 1sojods23?

如何用1取代env1,用2替换env2,用3替换env3,这样我之后会有一个新的字符串1sojods23?

6 个解决方案

#1


36  

Strings in Java are immutable, which makes this somewhat tricky if you are talking about an arbitrary number of things you need to find and replace.

Java中的字符串是不可变的,如果你在讨论需要查找和替换的任意数量的东西,这会使这有点棘手。

Specifically you need to define your replacements in a Map, use a StringBuffer and the appendReplacements() and appendTail() methods from Matcher. The final result will be stored in your StringBuffer.

具体来说,您需要在Map中定义替换,使用StringBuffer以及Matcher中的appendReplacements()和appendTail()方法。最终结果将存储在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());

Output:

输出:

1sojods23

#2


8  

I know this is old, I was myself looking for a, appendReplacement/appendTail example when I found it; However, the OP's question doesn't need those complicated multi-line solutions I saw here.

我知道这是旧的,当我找到它时,我自己正在寻找一个appendReplacement / appendTail示例;然而,OP的问题并不需要我在这里看到的那些复杂的多线解决方案。

In this exact case, when the string to replace holds itself the value we want to replace with, then this could be done easily with replaceAll:

在这种情况下,当要替换的字符串保存自己要替换的值时,可以使用replaceAll轻松完成:

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

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

// Output => 1sojods23

DEMO

DEMO

When the replacement is random based on some conditions or logic on each match, then you can use appendReplacement/appendTail for example

当基于每个匹配的某些条件或逻辑替换是随机的时,您可以使用appendReplacement / appendTail作为示例

#3


2  

Hopefully you would find this code useful:

希望您会发现此代码有用:

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

The output is the expected: 1sojods23.

输出是预期的:1sojods23。

#4


2  

This gives you 1sojods23:

这给你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);

and this works too:

这也有效:

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

#5


0  

You can use a StringBuffer in combination with the Matcher appendReplacement() method, but if the the pattern does not match, there is no point in creating the StringBuffer.

您可以将StringBuffer与Matcher appendReplacement()方法结合使用,但如果模式不匹配,则创建StringBuffer没有意义。

For example, here is a pattern that matches ${...}. Group 1 is the contents between the braces.

例如,这是一个匹配$ {...}的模式。第1组是大括号之间的内容。

static Pattern rxTemplate = Pattern.compile("\\$\\{([^}\\s]+)\\}");

And here is sample function that uses that pattern.

这是使用该模式的示例函数。

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


-1  

Use groups once it is matched ${env1} will be your first group and then you use regex to replace what is in each group.

匹配后使用组$ {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;)

#1


36  

Strings in Java are immutable, which makes this somewhat tricky if you are talking about an arbitrary number of things you need to find and replace.

Java中的字符串是不可变的,如果你在讨论需要查找和替换的任意数量的东西,这会使这有点棘手。

Specifically you need to define your replacements in a Map, use a StringBuffer and the appendReplacements() and appendTail() methods from Matcher. The final result will be stored in your StringBuffer.

具体来说,您需要在Map中定义替换,使用StringBuffer以及Matcher中的appendReplacements()和appendTail()方法。最终结果将存储在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());

Output:

输出:

1sojods23

#2


8  

I know this is old, I was myself looking for a, appendReplacement/appendTail example when I found it; However, the OP's question doesn't need those complicated multi-line solutions I saw here.

我知道这是旧的,当我找到它时,我自己正在寻找一个appendReplacement / appendTail示例;然而,OP的问题并不需要我在这里看到的那些复杂的多线解决方案。

In this exact case, when the string to replace holds itself the value we want to replace with, then this could be done easily with replaceAll:

在这种情况下,当要替换的字符串保存自己要替换的值时,可以使用replaceAll轻松完成:

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

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

// Output => 1sojods23

DEMO

DEMO

When the replacement is random based on some conditions or logic on each match, then you can use appendReplacement/appendTail for example

当基于每个匹配的某些条件或逻辑替换是随机的时,您可以使用appendReplacement / appendTail作为示例

#3


2  

Hopefully you would find this code useful:

希望您会发现此代码有用:

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

The output is the expected: 1sojods23.

输出是预期的:1sojods23。

#4


2  

This gives you 1sojods23:

这给你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);

and this works too:

这也有效:

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

#5


0  

You can use a StringBuffer in combination with the Matcher appendReplacement() method, but if the the pattern does not match, there is no point in creating the StringBuffer.

您可以将StringBuffer与Matcher appendReplacement()方法结合使用,但如果模式不匹配,则创建StringBuffer没有意义。

For example, here is a pattern that matches ${...}. Group 1 is the contents between the braces.

例如,这是一个匹配$ {...}的模式。第1组是大括号之间的内容。

static Pattern rxTemplate = Pattern.compile("\\$\\{([^}\\s]+)\\}");

And here is sample function that uses that pattern.

这是使用该模式的示例函数。

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


-1  

Use groups once it is matched ${env1} will be your first group and then you use regex to replace what is in each group.

匹配后使用组$ {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;)