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.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('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]This regex is designed to work well in most environments, including Python, JavaScript, and PCRE (Perl Compatible Regular Expressions).