ossobuko ossobuko - 13 days ago 5
Java Question

Finding special strings within special strings in strings with Regex

There is a HashMap I have which has keys and values inside. I want to replace keys with the values from the map in a string.

In the string, keys are written as this @keyName or @"keyName" these should be replaced with map.get("keyName")

Lets say our map is this

"key1" : "2"
"key2" : "3"
"key3" : "4"
"key 4" : "5"
"key-5" : "6"


So if we process the string "hello world, I am @key1 years old.", it will become "hello world, I am 2 years old."

Instead of @key1, we could use @"key1". If we use it without quotes, a white space (space character) or EOF should follow the key name and the key name shouldn't have white space in it. But if the key name has a white space in it, then it should be in quotes.

And if we process the string "hello world, I am @"key@"key1"" years old.", at first step it should replace the special string inside the special string and become "hello world, I am @"key2" years old." and then with the second step it should be "hello world, I am 3 years old."

I have already done it for one special string, it doesn't recognize the special string within the special string. Here is the code:

private static Pattern specialStringPattern = Pattern.compile("@\"([^\"]*?)\"|@\\S+");

/** this replaces the keys inside a string with their values.
* for example @keyName or @"keyName" is replaced with the value of the keyName. */
public static String specialStrings(String s) {
Matcher matcher = specialStringPattern.matcher(s);
while (matcher.find()) {
String text = matcher.group();
text = text.replace("@","").replaceAll("\"","");
s = s.replace(matcher.group(),map.get(text));
}
return s;
}


Sorry for my English, and my lack of Regex knowledge. I think it should be easy to get the answer by modifying the code a little bit.

Here is some examples of what I need:

There is @key1 apples on the table.
There is 2 apples on the table.

There is @"key1" apples on the table.
There is 2 apples on the table.

There is @key 4 apples on the table.
There is null 4 apples on the table.

There is @"key 4" apples on the table.
There is 5 apples on the table.

There is @key@key2 apples on the table.
There is @key3 apples on the table. (second step)
There is 4 apples on the table. (final output)

There is @"key @"key3"" apples on the table.
There is @"key 4" apples on the table. (second step)
There is 5 apples on the table. (final output)

There is @"key @key3" apples on the table.
There is @"key 4" apples on the table. (second step)
There is 5 apples on the table. (final output)

There is @"key @key3 " apples on the table.
There is @"key 4 " apples on the table. (second step)
There is null apples on the table. (final output)

There is @key-5 apples on the table.
There is 6 apples on the table.

Answer

I made regex that matching your example here: https://regex101.com/r/nudYEl/2

@(\"[\w\s]+\")|(?!@(\w+)@(\w+))@(\w+)

and you just need to modify your function to recursive:

public static String specialStrings(String s) {
    Matcher matcher = specialStringPattern.matcher(s);
    boolean findAgain = false;
    while (matcher.find()) {
        String text = matcher.group();
        text = text.replace("@","").replaceAll("\"","");
        s = s.replace(matcher.group(),map.get(text));
        findAgain = true;
    }
    if (findAgain) return specialStrings(s);
    return s;
}

[Update]
regex: https://regex101.com/r/nudYEl/4

@(\"[\w\s-]+\")|(?!@([\w-]+)@([\w-]+))@([\w-]+)

Comments