Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse user-defined format in Java

I am working on a format parser in Java and have some trouble with that. The format is stored so that users can change it to their likings.

format: '[prefix] [name] [suffix]: [msg]'

To put my values in the format I use String.replace() in Java.

format = getFormatTemplate(); // '[prefix] [name] [suffix]: [msg]'

format = format.replace("[prefix]", prefix); // prefix = "Hello";
format = format.replace("[name]", name); // name = "username";
format = format.replace("[suffix]", suffix); // suffix = "World";
format = format.replace("[msg]", msg); // msg = "Test message";

This will result in the output Hello username World: Test message as I expect. But when some parts of the string are empty there will be a space there.

When for example the suffix is empty the output will be Hello username : Test message note the space between the name and the :

How can I get rid of that so that some parts can be empty without breaking the user defined format?

Is there a better way to parse and apply the format?

like image 627
svenar Avatar asked Jun 28 '20 19:06

svenar


People also ask

What is format parse in Java?

The format() method of this class accepts a java. util. Date object and returns a date/time string in the format represented by the current object. Therefore, to parse a date String to another date format − Get the input date string.

What is SDF parse?

SimpleDateFormat parse() Method in Java with Examples The parse() Method of SimpleDateFormat class is used to parse the text from a string to produce the Date. The method parses the text starting at the index given by a start position.

What is the difference between parse and format in Java?

format() returns correct current time of the given Timezone, but SimpleDateFormat. parse() returns local current time, I don't know why this is happening. Time1 is the output of "America/Los_Angeles" and Time2 is the output of local (i.e. "Asia/Calcutta").

What is the use of SimpleDateFormat in Java?

SimpleDateFormat is a concrete class for formatting and parsing dates in a locale-sensitive manner. It allows for formatting (date -> text), parsing (text -> date), and normalization. SimpleDateFormat allows you to start by choosing any user-defined patterns for date-time formatting.


1 Answers

The following method will do the job:

static String replace(String text, Map<String, String> values) {
    StringBuilder result = new StringBuilder();
    int textIdx = 0;
    for (int startIdx; (startIdx = text.indexOf('[', textIdx)) != -1; ) {
        int endIdx = text.indexOf(']', startIdx + 1);
        if (endIdx == -1)
            break;
        result.append(text.substring(textIdx, startIdx));
        textIdx = endIdx + 1;
        String value = values.get(text.substring(startIdx + 1, endIdx));
        if (value != null && ! value.isEmpty()) {
            result.append(value); // Replace placeholder with non-empty value
        } else if (result.length() != 0 && result.charAt(result.length() - 1) == ' ') {
            result.setLength(result.length() - 1); // Remove space before placeholder
        } else if (textIdx < text.length() && text.charAt(textIdx) == ' ') {
            textIdx++; // Skip space after placeholder
        }
    }
    result.append(text.substring(textIdx));
    return result.toString();
}

Test

public static void main(String[] args) {
    test("[prefix] [name] [suffix]: [msg]",
         Map.of("prefix", "Hello",
                "name", "username",
                "suffix", "World",
                "msg", "Test message"));
    test("[prefix] [name] [suffix]: [msg]",
         Map.of("name", "username",
                "suffix", "World",
                "msg", "Test message"));
    test("[prefix] [name] [suffix]: [msg]",
         Map.of("prefix", "Hello",
                "suffix", "World",
                "msg", "Test message"));
    test("[prefix] [name] [suffix]: [msg]",
         Map.of("prefix", "Hello",
                "name", "username",
                "msg", "Test message"));
    test("[prefix] [name] [suffix]: [msg]",
         Map.of("prefix", "Hello",
                "name", "username",
                "suffix", "World"));
    test("[prefix] [name] [suffix]: [msg]",
         Map.of());
}

static void test(String text, Map<String, String> values) {
    System.out.println('"' + replace(text, values) + '"');
}

Output

"Hello username World: Test message"
"username World: Test message"
"Hello World: Test message"
"Hello username: Test message"
"Hello username World:"
":"

Notice how multiple spaces are correctly eliminated when consecutive placeholders are missing/empty.

like image 125
Andreas Avatar answered Oct 04 '22 21:10

Andreas