使用 Regex Replace with repeating pattern 追加

Append using Regex Replace with repeating pattern

我在 Java 程序中需要 append/replace 以下模式。

示例字符串:

1: {\"values" : ["AnyValue1", "TestValue", "Dummy", "SomeValue"], "key" : "value"}

2: {\"otherValue\": \"AnyValue1\", \n" + "\"values\" : [\"AnyValue1\", \"TestValue\", \"Dummy\", \"SomeValue\"], \"key\" : \"value\"}

此值数组中可以有 N 个值。

我需要为所有值附加 _val。但是,只有 values 内的值应该附加 _val

Output 1: { "values" : ["AnyValue1_val", "TestValue_val", "Dummy_val", "SomeValue_val"], "key" : "value" }

Output 2: {"otherValue": "AnyValue1", 
          "values" : ["AnyValue1_val", "TestValue_val", "Dummy_val", "SomeValue_val"], "key" : "value"}

我想知道我是否可以使用正则表达式替换而不是通过循环?

内容在一个字符串中:

String content = "{ \"values\" : [\"AnyValue1\", \"TestValue\", \"Dummy\", \"SomeValue\"], \"key\" : \"value\" }";

我已经为您的问题工作了几分钟。我想出了一个解决方案。它可能不是最好的,因为我不太习惯使用正则表达式。


概念

这是一个两步解决方案:

1st step: Obtain the substring between [...] using regex.
2nd step: Obtain all the substring between "..." and append "_val" in the end.

我们之所以需要先获取[...]之间的子字符串是因为如果我们直接应用第二步,那么“values”、“key”和“value”也将是变了。这不是你想要的。


代码

//Set the string
String str = "{\"otherValue\": \"AnyValue1\", \n" + "\"values\" : [\"AnyValue1\", \"TestValue\", \"Dummy\", \"SomeValue\"], \"key\" : \"value\"}";

//Set the first pattern to find the substring between [...]
Pattern pattern1 = Pattern.compile("(?<=\[).*(?=])");
Matcher matcher1 = pattern1.matcher(str);

//To locate part of string not to replace
int startIndex;
int endIndex;

if (matcher1.find())
{
    String values = matcher1.group();
    startIndex = matcher1.start();
    endIndex = matcher1.end();
     
    //Set the first pattern to find all the substring between "..."
    Pattern pattern2 = Pattern.compile("(?<=\")[a-zA-z0-9]+(?=\")");
    Matcher matcher2 = pattern2.matcher(values);

    while (matcher2.find())
    {
        values = values.replace(matcher2.group(), matcher2.group()+"_val");
    }

    System.out.println(str.substring(0, startIndex) + values + str.substring(endIndex));
}

输出

{"otherValue": "AnyValue1", 
"values" : ["AnyValue1_val", "TestValue_val", "Dummy_val", "SomeValue_val"], "key" : "value"}

希望对您有所帮助。 java.util.regex.Patternjava.util.regex.Matcher class 中可能存在更好的方法,这些方法可能会以更简单的方式做事。也许他们可以在一个命令中替换所有子字符串。但是,我不经常使用这些 class 所以我不熟悉它。

如果您对使用的正则表达式有任何疑问,请发表评论。

PS: 如果有人发现我的回答有任何改进,特别是如果它可以变得更简单,请提出来。我发现我目前的答案有点复杂。我觉得还可以改进。

试试这个。

String content = "{ \"values\" : [\"AnyValue1\", \"TestValue\", \"Dummy\", \"SomeValue\"], \"key\" : \"value\" }";
Pattern bracket = Pattern.compile("\[.*?\]");
Pattern string = Pattern.compile("\"(.*?)\"");
String result =  bracket.matcher(content)
    .replaceAll(m -> string.matcher(m.group())
        .replaceAll(n -> "\"" + n.group(1) + "_val\""));
System.out.println(result);

输出:

{ "values" : ["AnyValue1_val", "TestValue_val", "Dummy_val", "SomeValue_val"], "key" : "value" }

选择:

public static void main(String[] args) {
    String input = "{ \"values\" : [\"AnyValue1\", \"TestValue\", \"Dummy\", \"SomeValue\"], \"key\" : \"value\" }";

    Matcher matcher = Pattern.compile("(.*?\[)(.*?)(\].*)").matcher(input);
    if(matcher.find()) {
        String val = matcher.group(2).replaceAll("(\w+)", "_val");
        System.out.println(matcher.group(1) + val + matcher.group(3));
    }
}

输出:

{ "values" : ["AnyValue1_val", "TestValue_val", "Dummy_val", "SomeValue_val"], "key" : "value" }