2009-11-30 18 views
25

Necesito una expresión regular que pueda eliminar la extensión de un nombre de archivo, devolviendo solo el nombre del archivo.Expresión regular para eliminar la extensión de un archivo

Éstos son algunos ejemplos de entradas y salidas:

myfile.png  -> myfile 
myfile.png.jpg -> myfile.png 

que puedo hacer, obviamente, esto manualmente (es decir, la eliminación de todo, desde el último punto), pero estoy seguro de que hay una expresión regular que puede hacer esto por sí mismo.

Sólo para que conste, estoy haciendo esto en JavaScript

Respuesta

33
/(.*)\.[^.]+$/ 

resultado será que en el primer grupo de captura. Sin embargo, probablemente sea más eficiente simplemente encontrar la posición del período más a la derecha y luego tomar todo antes, sin usar expresiones regulares.

+0

También piense en cosas como 'a.longthingrighthereattheend' o' .ext' & 'file'. Tal vez consulte con '/ (. *) \. [^.] {1,10} $ /'. En realidad, solo usa 'pathinfo()'. – Xeoncross

+0

Una solución casi perfecta pero, si quiere evitar la trampa de nombres de archivos como .htaccess (comienza con un punto, pero no tiene extensión), como lo ejemplifica Roger Pate, simplemente sustituya el primer asterisco por una señal más, de la siguiente manera: (. +) \. [^.] + $ – aldemarcalazans

4

La expresión regular para que coincida con el patrón es:

/\.[^.]*$/ 

encuentra un carácter de punto (. \), seguido de 0 o más caracteres que no son períodos ([^.] *), seguido por el final de la cadena ($).

+1

/.\w*$/.exec("myfile.png ") => [" .png "] –

+0

Esa expresión regular devuelve la extensión, mientras que necesito eliminarla la extensión –

+0

lea la pregunta pls – mahatmanich

-2

En javascript puede llamar al método Replace() que reemplazará en función de una expresión regular.

Esta expresión regular coincidirá con todo, desde el comienzo de la línea hasta el final y eliminará todo después del último período, incluido el período.

/^(.*)\..*$/ 

El modo de implementar la sustitución se puede encontrar en esta pregunta de Stackoverflow.

Javascript regex question

+0

En realidad, como actualmente lo tiene escrito, eliminará todo después de incluir el * primero * período, ya que tiene su grupo de captura configurado para ser no codicioso, y su último '. *' puede coincidir con cualquier cosa, incluidos los puntos. – Amber

+0

Sí, me di cuenta de que después de publicar inicialmente y luego lo actualicé. Gracias – Tinidian

+0

@Amber ¿Qué hace que su grupo de captura no sea codicioso? Pensé. * Siempre es codicioso. . *? sería perezoso Y ese patrón parece funcionar^(. *) \ .. * $ – barlop

68

simplemente para la corrección: ¿Cómo podría lograrse sin expresiones regulares?

var input = 'myfile.png'; 
var output = input.substr(0, input.lastIndexOf('.')) || input; 

El || input se encarga del caso, donde lastIndexOf() proporciona un -1. Usted ve, todavía es un trazador de líneas.

+3

¡Me gustó mucho lo que hizo con la entrada/salida! :) –

+1

¡Buena solución! Tuve tunnelvision en RegEx, pero esto también funciona – Jareish

+0

De forma similar, usando [underscore.string] (https://github.com/epeli/underscore.string): 'var output = _s.strLeftBack (input, '.'); // 'myfile'' –

11
/^(.+)(\.[^ .]+)?$/ 

casos de exámenes en que esto funciona y otros fracasan:

  • ".htaccess" (período anterior)
  • "archivo" (sin extensión)
  • "enviar a la Sra." (Sin extensión, pero termina en abbr.)
  • "versión 1.2 de proyecto" (sin extensión, sin embargo, todavía contiene un período)

El hilo común de arriba es, por supuesto, las extensiones de archivo "malformados". Pero siempre debes pensar en esos casos de esquina.: P

casos de exámenes en que esto no funciona:

    "versión 1.2"
  • (sin extensión de archivo, pero "parece" tener uno)
  • "name.tar.gz" (si ha visto este como una "extensión compuesta" y quería dividirla en "nombre" y ".tar.gz")

Cómo manejar esto es problemático y se decide mejor según el proyecto.

0

Esto lo hará así :)

'myfile.png.jpg'.split('.').reverse().slice(1).reverse().join('.'); 

Me gustaría poner a la expresión regular, aunque ... = P

4
/^(.+)(\.[^ .]+)?$/ 

patrón de Arriba está mal - siempre va a incluir la extensión también. Es por la forma en que funciona el motor javascript regex. El token (\.[^ .]+) es opcional para que el motor coincidirá con éxito toda la cadena con (.+) http://cl.ly/image/3G1I3h3M2Q0M


aquí está mi solución expresión regular probado.

El patrón coincidirá filenameNoExt con/sin extensión en el camino, respetando tanto la barra y los separadores de barra invertida

var path = "c:\some.path/subfolder/file.ext" 
var m = path.match(/([^:\\/]*?)(?:\.([^ :\\/.]*))?$/) 
var fileName = (m === null)? "" : m[0] 
var fileExt = (m === null)? "" : m[1] 

disección del patrón de arriba:

([^:\\/]*?) // 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

Esto cubrirá todos los casos que se mencionan por @RogerPate pero incluyendo también las rutas completas

0
return filename.split('.').pop(); 

que hará que su deseo se haga realidad. Pero no es una forma de expresión regular.

+2

Esto está mal, devolverá la extensión de archivo y no el nombre de archivo, que se solicitó en la pregunta. –

+0

Puede usar shift() en lugar de pop(). – simonox

1

otra hay forma de expresiones regulares de hacerlo el "opuesto" o la versión de Raul (sin utilizar pop() para eliminar)

No requiere hacer referencia a la variable dos veces, por lo que es más fácil de inline

filename.split('.').slice(0,-1).join() 
Cuestiones relacionadas