2012-01-25 7 views
6

Estoy seguro que esto debe ser lo suficientemente fácil, pero estoy luchando ...nombre del partido y la extensión de archivo de una sola expresión regular

var regexFileName = /[^\\]*$/; // match filename 
var regexFileExtension = /(\w+)$/; // match file extension 

function displayUpload() { 
    var path = $el.val(); //This is a file input 
    var filename = path.match(regexFileName); // returns file name 
    var extension = filename[0].match(regexFileExtension); // returns extension 

    console.log("The filename is " + filename[0]); 
    console.log("The extension is " + extension[0]); 
} 

La función anterior funciona bien, pero estoy seguro que debe ser Es posible lograrlo con una sola expresión regular, al hacer referencia a diferentes partes de la matriz devuelta con el método .match(). Intenté combinar estas expresiones regulares pero sin éxito.

Además, no estoy usando una cadena para probarlo en el ejemplo, como console.log() se escapa de las barras invertidas en una ruta de archivo y que estaba empezando a confundir a mí :)

Respuesta

5

Suponiendo que todos los archivos tienen una extensión, se puede usar

var regexAll = /[^\\]*\.(\w+)$/; 

a continuación, puede hacer

var total = path.match(regexAll); 
var filename = total[0]; 
var extension = total[1]; 
+0

Yo soy más de un tipo de expresiones regulares de .NET pero no se ¿Te estás perdiendo el primer grupo de captura? – rtpHarry

+0

@rtpHarry: la coincidencia completa (grupo 0) es el nombre de archivo (incluida la extensión), el primer grupo de captura (grupo 1) es la extensión. –

+0

Necesita el nombre del archivo, no todo el camino. – shift66

6

/^.*\/(.*)\.?(.*)$/g después de este primer grupo es su nombre de archivo y el segundo grupo es extensión.

var myString = "filePath/long/path/myfile.even.with.dotes.TXT"; 
var myRegexp = /^.*\/(.*)\.(.*)$/g; 
var match = myRegexp.exec(myString); 
alert(match[1]); // myfile.even.with.dotes 
alert(match[2]); // TXT 

Esto funciona incluso si su nombre de archivo contiene más de un DoTes o no contiene puntos en absoluto (no tiene extensión).
EDIT:
Esto es para Linux, para Windows utilizan este /^.*\\(.*)\.?(.*)$/g (en Linux separador de directorio es / en las ventanas es \)

+0

Esta falla con ' '/ tmp/myFile.txt'' – DelightedD0D

2

se pueden utilizar grupos en años ur expresión regular para esto:

var regex = /^([^\\]*)\.(\w+)$/; 
var matches = filename.match(regex); 

if (matches) { 
    var filename = matches[1]; 
    var extension = matches[2]; 
} 
+0

Soy más un tipo de regex de .net pero ¿no te estás perdiendo el primer grupo de captura? – rtpHarry

+0

Tienes razón. Acabo de probarlo, la documentación era un poco confusa al respecto: P – fivedigit

+0

Su código era correcto antes y ahora está roto. ¿De dónde se supone que 'matches [2]' proviene si solo tienes un grupo de captura? –

0

creo que esto es un mejor enfoque que coincide sólo directorio válido, nombres de archivo y la extensión. y también agrupa la ruta, el nombre de archivo y la extensión de archivo. Y también funciona con rutas vacías solo nombre de archivo.

^([\w\/]*?)([\w\.]*)\.(\w)$ 

Los casos de prueba

the/p0090Aath/fav.min.icon.png 
the/p0090Aath/fav.min.icon.html 
the/p009_0Aath/fav.m45in.icon.css 
fav.m45in.icon.css 
favicon.ico 

salida

[the/p0090Aath/][fav.min.icon][png] 
[the/p0090Aath/][fav.min.icon][html] 
[the/p009_0Aath/][fav.m45in.icon][css] 
[][fav.m45in.icon][css] 
[][favicon][ico] 
2

Esto reconocer incluso /home/someUser/.aaa/.bb.c:

function splitPathFileExtension(path){ 
    var parsed = path.match(/^(.*\/)(.*)\.(.*)$/); 
    return [parsed[1], parsed[2], parsed[3]]; 
} 
0

Sé que esto es una vieja pregunta, pero aquí hay otra solución que puede manejar múltiples puntos en el nombre y también cuando no hay ninguna extensión (o una extensión de poco ''):
/^(.*?)(\.[^.]*)?$/

Si lo toma una pieza a la vez:
^
ancla al inicio de la cadena (para evitar coincidencias parciales)

(.*?)
cualquier carácter ., 0 o más veces *, perezosamente ? (no basta con agarrar a todos si la extensión opcional puede coincidir más tarde), y ponerlos en el primer grupo de captura ().

(\.
inicia un Grupo de captura para la segunda extensión usando (. Este grupo comienza con el carácter literal . (que se escapa con \ para que . no se interprete como "coincida con ningún carácter").

[^.]*
definir un juego de caracteres []. Coincidir caracteres no en el conjunto especificando que este es un conjunto de caracteres invertidos ^. Coincide con 0 o más caracteres no . para obtener el resto de la extensión de archivo *. Lo especificamos de esta manera para que no coincida temprano en nombres de archivo como foo.bar.baz, dando una extensión incorrecta con más de un punto en el .bar.baz en lugar de solo .baz. . no necesita escapó dentro de [], ya que todo (excepto ^) es un literal en un juego de caracteres.

)?
End el segundo grupo de captura ) e indican que todo el grupo es opcional ?, ya que no puede tener una extensión.

$
ancla al final de la cadena (de nuevo, para evitar coincidencias parciales)

Si está utilizando ES6 incluso se puede utilizar destructing para agarrar los resultados en la línea 1:
[,filename, extension] = /^(.*?)(\.[^.]*)?$/.exec('foo.bar.baz'); cuales da el nombre de archivo como 'foo.bar' y la extensión como '.baz'.
'foo' da 'foo' and ''
'foo.' da 'foo' y '.'
'.js' da '' y '.js'

Cuestiones relacionadas