1

Hi I tried using this regular expression

^(?=[^,]+,[^,]+$)[a-zA-Z,]{1,20}$

But it didn't work.

Is there any way to achieve this?

Mean to say that,while saving the file from file writting, file name should be less than or equal to 20 characters long and characters after 20 should get trimmed.

drs_india
  • 21
  • 5
  • 1
    Possible duplicate of [Limit length of characters in a regular expression?](http://stackoverflow.com/questions/2616974/limit-length-of-characters-in-a-regular-expression) – horatius Jan 07 '16 at 07:16
  • Why are there two dollar signs? – Thorbjørn Ravn Andersen Jan 07 '16 at 07:19
  • can you creect your tags please. There is no nsreg... in java – Jens Jan 07 '16 at 07:21
  • 1
    See [this demo](https://ideone.com/wAyRpf) (`.replaceFirst("^(?=[^,]+,[^,]+$)([a-zA-Z,]{1,20})[a-zA-Z,]*$", "$1")`), but I suspect Ken's answer should be close to what you should really be using. – Wiktor Stribiżew Jan 07 '16 at 07:47
  • it is not clear at all. restrict a String is simple (see answer of K. Bekov), regular expression is not for that, but what kind of file name do you want to cut ? Are there some rule about the name ? – guillaume girod-vitouchkina Jan 07 '16 at 07:52
  • Using a regex for this task will be 1. hard to write and 2. hard to read. I suggest you make two checks: one for the length and one for the format itself. – Olivier Grégoire Jan 07 '16 at 09:51

2 Answers2

1

You don't need regexp for trim string:

if(fileName.length()>20){
   filename = filename.substring(0, 20);
}
Ken Bekov
  • 13,696
  • 3
  • 36
  • 44
0

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);
}
Community
  • 1
  • 1
Stephan
  • 41,764
  • 65
  • 238
  • 329