Frithjof Frithjof - 1 month ago 18
Java Question

Case-insensitive String Substitutor

I am using org.apache.commons.lang3.text.StrSubstitutor to parse a String. I have it setup similar to this:

StrSubstitutor sub = new StrSubstitutor(messageValues, "&(", ")");
String format = sub.replace("Information: &(killer) killed &(target)!");


This no longer works if I wright the keys in different cases:

"Information: &(KILLER) killed &(TARGET)!"


Is there a way of making the keys for the String Substitutor case-insensitive?

I cannot use
toLowerCase()
because I only want the keys to be case-insensitive.

Answer

StrSubstitutor has a constructor that takes an instance of StrLookup. You can create an implementation of StrLookup that lowercases the keys its looking for before actually looking for them.

Here's how it looks like:

public class CaseInsensitiveStrLookup<V> extends StrLookup<V> {

private final Map<String, V> map;

CaseInsensitiveStrLookup(final Map<String, V> map) {
    this.map = map;
}

@Override
public String lookup(final String key) {
    String lowercaseKey = key.toLowerCase(); //lowercase the key you're looking for
    if (map == null) {
        return null;
    }
    final Object obj = map.get(lowercaseKey);
    if (obj == null) {
        return null;
    }
    return obj.toString();
}
}

Using this StrLookup implementation you don't need to worry about what kind of Map you're passing to the constructor.

The following test case returns succesfully, using the above implementation:

import org.apache.commons.lang3.text.StrSubstitutor;
import org.testng.Assert;
import org.testng.annotations.Test;

import java.util.HashMap;
import java.util.Map;

@Test
public class TestClass {

@Test
public void test() {

    Map<String, String> messageValues = new HashMap<String, String>();
    messageValues.put("killer", "Johnson");
    messageValues.put("target", "Quagmire");
    StrSubstitutor sub = new StrSubstitutor(new CaseInsensitiveStrLookup<String>(messageValues), "&(", ")", '\\');

    String format2 = sub.replace("Information: &(killer) killed &(target)!");
    String format = sub.replace("Information: &(KILLER) killed &(TARGET)!");
    Assert.assertEquals(format, "Information: Johnson killed Quagmire!");
    Assert.assertEquals(format2, "Information: Johnson killed Quagmire!");
}
}
Comments