expressão regular para remover extensão de um arquivo
-
10-07-2019 - |
Pergunta
Eu estou precisando de uma expressão regular que pode remover a extensão de um nome de arquivo, retornando somente o nome do arquivo.
Aqui estão alguns exemplos de entradas e saídas:
myfile.png -> myfile
myfile.png.jpg -> myfile.png
Eu, obviamente, pode fazer isso manualmente (ou seja, remover tudo, desde o último ponto), mas tenho certeza de que não é uma expressão regular que pode fazer isso por si só.
Apenas para o registro, eu estou fazendo isso em JavaScript
Solução
/(.*)\.[^.]+$/
resultado será nesse primeiro grupo de captura. No entanto, é provavelmente mais eficiente para apenas encontrar a posição do período mais à direita e, em seguida, levar tudo antes, sem o uso de regex.
Outras dicas
Apenas para ser completo:? Como isso pode ser alcançado sem Expressões Regulares
var input = 'myfile.png';
var output = input.substr(0, input.lastIndexOf('.')) || input;
O || input
cuida do caso, onde lastIndexOf()
fornece uma -1
. Você vê, ainda é um one-liner.
/^(.+)(\.[^ .]+)?$/
Os casos de teste, onde funciona este e outros não:
- "htaccess" (período anterior)
- "file" (sem extensão de arquivo)
- "Enviar para mrs." (Sem extensão, mas termina em abbr.)
- "versão 1.2 do projeto" (sem extensão, mas ainda contém um período)
O fio comum acima é, obviamente, "mal formada" extensões de arquivo. Mas você sempre tem que pensar sobre os casos de canto. : P
Os casos de teste onde esta falha:
- "versão 1.2" (sem extensão de arquivo, mas "parece" ter um)
- "name.tar.gz" (se você ver isso como uma "extensão composto" e queria que dividido em "nome" e ".tar.gz")
Como lidar com estes é problemático e melhor decididas numa base específica do projeto.
A expressão regular para corresponder ao padrão é:
/\.[^.]*$/
Ele encontra uma personagem período (
console.log(
"aaa.bbb.ccc".replace(/\.[^.]*$/,'')
)
/^(.+)(\.[^ .]+)?$/
Acima padrão está errado - ele vai sempre incluir a extensão também. É por causa da forma como o motor de javascript regex funciona. O (\.[^ .]+)
token é opcional assim que o motor irá corresponder com sucesso toda a string com (.+)
http://cl.ly/image/3G1I3h3M2Q0M
Aqui está a minha solução regexp testado.
O padrão irá corresponder filenameNoExt com / sem extensão no caminho, respeitando tanto barra e barra invertida separadores
var path = "c:\some.path/subfolder/file.ext"
var m = path.match(/([^:\\/]*?)(?:\.([^ :\\/.]*))?$/)
var fileName = (m === null)? "" : m[0]
var fileExt = (m === null)? "" : m[1]
dissecção do padrão acima:
([^:\\/]*?) // match any character, except slashes and colon, 0-or-more times,
// make the token non-greedy so that the regex engine
// will try to match the next token (the file extension)
// capture the file name token to subpattern \1
(?:\. // match the '.' but don't capture it
([^ :\\/.]*) // match file extension
// ensure that the last element of the path is matched by prohibiting slashes
// capture the file extension token to subpattern \2
)?$ // the whole file extension is optional
http://cl.ly/image/3t3N413g3K09
http://www.gethifi.com/tools/regex
Isto irá cobrir todos os casos que foi mencionado por @RogerPate mas incluindo caminhos completos demasiado
outra maneira não-regex de fazê-lo (o "oposto" de @ versão de Rahul, não usar pop () para remover)
Não requer para se referir à variável duas vezes, por isso é mais fácil de linha
filename.split('.').slice(0,-1).join()
Isto irá fazê-lo também:)
'myfile.png.jpg'.split('.').reverse().slice(1).reverse().join('.');
Eu furar a regexp embora ... = P
return filename.split('.').pop();
ele vai fazer o seu sonho em realidade. Mas não modo de expressão regular.
Em JavaScript você pode chamar o método replace () que irá substituir com base em uma expressão regular.
Esta expressão regular irá corresponder a tudo, desde o início da linha até o fim e remover qualquer coisa após o último período, incluindo o período.
/^(.*)\..*$/
A como de implementar a substituir podem ser encontrados nesta questão Stackoverflow.