user
Write a regular expression that separate filename from extension, if there is no extension, returns only the filename and group 2 is empty. If the filename has several dots only the last one is for the extension.
alphonsio

You can use the following regex pattern to separate the filename from the extension, handling cases where there might not be an extension:

^(.*?)(?:\.([^\.]+))?$

Here's how the regex works:

  • ^(.*?): This captures the filename. The ^ asserts the start of a string, and (.+?) captures zero or more of any characters, non-greedy (as little as possible).
  • (?:\.([^\.]+))?: This is a non-capturing group for the extension section:
    • \.: Matches the literal dot.
    • ([^\.]+): Captures one or more characters that are not a dot. This is our file extension.
    • ?: Makes the entire non-capturing group optional, accounting for filenames without an extension.
  • $: Asserts the end of the line or string.

Examples:

const regex = /^(.*?)(?:\.([^.]+))?$/ 
console.log (regex.exec('filename.txt')) // ["filename.txt", "filename", "txt"]
console.log (regex.exec('file.name.txt')) // ["file.name.txt", "file.name", "txt"]
console.log (regex.exec('file.name.with.several.dots.txt')) // ["file.name.txt", "file.name", "txt"]
console.log (regex.exec('filename')) // ["filename", "filename", undefined]
console.log (regex.exec('file.name')) // ["file.name", "file", "name"]
console.log (regex.exec('.htaccess')) // [".htaccess", "", "htaccess"]
console.log (regex.exec('')) // ["", "", undefined]

Check the above example online on JSFiddle

This regex is designed to work well in most environments, including Python, JavaScript, and PCRE (Perl Compatible Regular Expressions).