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?
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.
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.
matcher(str). matches() .
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.
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);
}
You can use Java regular expressions - please see http://www.vogella.de/articles/JavaRegularExpressions/article.html
Thanks...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With