Search code examples
javastring-parsing

Parsing strings in Java to replace markers with specific data


I have a bunch of strings which contain some specific markers that should be replaced with images. So at first I created hash map with markers and images:

Map<String, String> images = new HashMap<String, String>();
images.put(":img:howdy:", "path/images/hello.png");
images.put(":img:code:", "path/images/code.png");
images.put(":img:smile:", "path/images/sm.png");
//...and 70 more records

Strings look like:

This is a string :img:howdy:, you know it :img:smile:

And even more:img:smile:

This is a string with images:img:code::img:smile:

After parsing all markers are planned to be replaced with images.

I stuck at the following point:

Map<String, String> images = new HashMap<String, String>();
images.put(":img:howdy:", "path/images/hello.png");
images.put(":img:code:", "path/images/code.png");
images.put(":img:smile:", "path/images/sm.png");

String[] strings = {"This is a string :img:howdy:, you know it :img:smile:",
                 "And even more:img:smile:",
                 "This is a string with images:img:code::img:smile:"};

for (String text : images.keySet()) {
    for (String string : strings) {
        if(string.contains(text)) {
            string.replace(text, images.get(text));
        }
    }
}

Firstly, markers are replaced, but there're to much iterations. Secondly, if I use, for example, StringBuilder, I have a lot of duplications with some markers replaced and some not.

I'm not strong with string parsing and corresponding algorithms (at the moment), so don't throw stones at me after viewing approach I chose.

Added Reworked a little as Dariusz Waver suggested and here is what I've got:

private final String IMAGE_PATTERN = ":s:\\w+:";

//.......

Pattern p = Pattern.compile(IMAGE_PATTERN);
Matcher m = p.matcher(message);
while(m.find())
{
    String imgPattern = message.substring(m.start(), m.end());
    String imgPath = ImgPaths.images.get(imgPattern);
    
    //If there's no such image in Images Map
    if(imgPattern != null) {
        message = message.replace(imgPattern, imgPath);
        m.reset(message);
    }
}

StringBuilder result = new StringBuilder();
result.append(timestamp).append(" - ").append(sender)
        .append(": ").append(message);

Is there any way to make it more optmized taking into account that there's a really huge amount of text?


Solution

  • I'd suggest doing it the other way around: first find all occurences of regex :\w+:\w+, then search for it's values in the map, and then, if they are found, replace the strings.

    For larger amounts of images and larger amounts of text it will be the better way to do it.

    Your code, however, is pretty clean and if you don't have any performance issues you can leave it as it is - provided you actually make the fix posted by jlordo:

    for (int i = 0; i < strings.length; i++) {
        if(strings[i].contains(text)) {
            strings[i] = strings[i].replace(text, images.get(text));
        }
    }