Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verify if String matches a format String

In Java, how can you determine if a String matches a format string (ie: song%03d.mp3)?

In other words, how would you implement the following function?

/**
* @return true if formatted equals String.format(format, something), false otherwise.
**/
boolean matches(String formatted, String format);

Examples:

matches("hello world!", "hello %s!"); // true
matches("song001.mp3", "song%03d.mp3"); // true
matches("potato", "song%03d.mp3"); // false

Maybe there's a way to convert a format string into a regex?

Clarification

The format String is a parameter. I don't know it in advance. song%03d.mp3 is just an example. It could be any other format string.

If it helps, I can assume that the format string will only have one parameter.

like image 864
hpique Avatar asked Aug 25 '11 11:08

hpique


People also ask

How do you know if a string matches a pattern?

You can use the Pattern. matches() method to quickly check if a text (String) matches a given regular expression. Or you can compile a Pattern instance using Pattern. compile() which can be used multiple times to match the regular expression against multiple texts.

How do I check if a string is in one format?

matcher(str). matches() .

How do you check if a string is formatted correctly Java?

Create a list of Formatter objects (one for each allowed pattern). Iterate that list; and try if you can parse your date string using each formatter (with lenient set to false!). If you get one that doesn't throw an exception, you know that the incoming string conforms to a valid format.


2 Answers

I don't know of a library that does that. Here is an example how to convert a format pattern into a regex. Notice that Pattern.quote is important to handle accidental regexes in the format string.

// copied from java.util.Formatter
// %[argument_index$][flags][width][.precision][t]conversion
private static final String formatSpecifier
    = "%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])";

private static final Pattern formatToken = Pattern.compile(formatSpecifier);

public Pattern convert(final String format) {
    final StringBuilder regex = new StringBuilder();
    final Matcher matcher = formatToken.matcher(format);
    int lastIndex = 0;
    regex.append('^');
    while (matcher.find()) {
        regex.append(Pattern.quote(format.substring(lastIndex, matcher.start())));
        regex.append(convertToken(matcher.group(1), matcher.group(2), matcher.group(3), 
                                  matcher.group(4), matcher.group(5), matcher.group(6)));
        lastIndex = matcher.end();
    }
    regex.append(Pattern.quote(format.substring(lastIndex, format.length())));
    regex.append('$');
    return Pattern.compile(regex.toString());
}

Of course, implementing convertToken will be a challenge. Here is something to start with:

private static String convertToken(String index, String flags, String width, String precision, String temporal, String conversion) {
    if (conversion.equals("s")) {
        return "[\\w\\d]*";
    } else if (conversion.equals("d")) {
        return "[\\d]{" + width + "}";
    }
    throw new IllegalArgumentException("%" + index + flags + width + precision + temporal + conversion);
}
like image 62
Cephalopod Avatar answered Sep 24 '22 17:09

Cephalopod


You can use Java regular expressions - please see http://www.vogella.de/articles/JavaRegularExpressions/article.html

Thanks...

like image 31
Prabath Siriwardena Avatar answered Sep 25 '22 17:09

Prabath Siriwardena