You can perform the check using regular expression only with a small enhancement in the regex (see stribizhev's comment).
private static final Matcher FILENAME_CHECKER = Pattern.compile("^(?=[^,]+,[^,]+$)([a-zA-Z,]{1,20})[a-zA-Z,]*$").matcher("");
/**
*
* ...filename requirements go here...
*
* @param unsanitizedFilename the filename to sanitize
* @return a sanitized filename
*
* @throws IllegalArgumentException If the filename doesn't honor all requirements.
*/
public static String sanitizeFilename(String unsanitizedFilename) {
FILENAME_CHECKER.reset(unsanitizedFilename);
if (FILENAME_CHECKER.find() == false) {
throw new IllegalArgumentException("Invalid filename: " + unsanitizedFilename);
}
return FILENAME_CHECKER.group(1);
}
Java 7+
If you're using Java 7+, you can use the version below and take advantage of named groups.
private static final Matcher FILENAME_CHECKER = Pattern.compile("^(?=[^,]+,[^,]+$)(?<valid_portion>[a-zA-Z,]{1,20})[a-zA-Z,]*$").matcher("");
public static String sanitizeFilename(String unsanitizedFilename) {
FILENAME_CHECKER.reset(unsanitizedFilename);
if (FILENAME_CHECKER.find() == false) {
throw new IllegalArgumentException("Invalid filename: " + unsanitizedFilename);
}
return FILENAME_CHECKER.group("valid_portion");
}
Thread safety
The Matcher
calss is not thread safe. If thread safety is a concern in your case, here is the thread safe version relying on the Pattern
class.
private static final Pattern FILENAME_CHECKER = Pattern.compile("^(?=[^,]+,[^,]+$)([a-zA-Z,]{1,20})[a-zA-Z,]*$");
/**
*
* ...filename requirements go here...
*
* @param unsanitizedFilename the filename to sanitize
* @return a sanitized filename
*
* @throws IllegalArgumentException If the filename doesn't honor all requirements.
*/
public static String sanitizeFilename(String unsanitizedFilename) {
Matcher m = FILENAME_CHECKER.matcher(unsanitizedFilename);
if (m.find() == false) {
throw new IllegalArgumentException("Invalid filename: " + unsanitizedFilename);
}
return m.group(1);
}