2009-03-09 58 views
12

Quiero obtener sólo el nombre de archivo usando expresiones regulares, por lo que he estado intentando cosas simples comoRegex: ¿Obtener nombre de archivo sin extensión en una sola toma?

([^\.]*) 

cuál de trabajo del curso sólo si el nombre del archivo tiene una extensión. Pero si es adfadsfads.blah.txt solo quiero adfadsfads.blah. ¿Cómo puedo hacer esto con Regex?

En cuanto a la pregunta de David, '¿por qué usarías expresiones regulares' para esto, la respuesta es 'por diversión'. De hecho, el código que estoy usando es sencilla

length_of_ext = File.extname(filename).length 
filename = filename[0,(filename.length-length_of_ext)] 

pero me gusta aprender expresiones regulares siempre que sea posible, ya que siempre aparece en las fiestas del friki.

+0

Daniel, en tal caso, le recomendaría comprar una herramienta como RegexBuddy. Es más divertido jugar con expresiones regulares si tienes una herramienta como esa. Incluso puedes depurar expresiones regulares en dicha herramienta. Realmente recomiendo eso. –

+0

Gracias David. Yo uso Regex Coach, que lo hace muy bien. –

Respuesta

33

Prueba esto:

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

Esta voluntad:

  • nombres de archivo de captura que comienzan con un punto (por ejemplo, ".logs" es un archivo llamado ".logs", no una extensión de archivo), que es común en Unix.
  • Obtiene todo menos el último punto: "foo.bar.jpeg" le otorga "foo.bar".
  • Maneja los archivos sin punto: "letra secreta" le da "carta secreta".

Nota: como j_random_hacker comentarista sugirió, esto lleva a cabo como se anuncia, pero es posible que desee preceder a las cosas con un ancla para facilitar la lectura.

+1

Hay una buena explicación de esto en http://www.movingtofreedom.org/2008/04/01/regex-match-filename-base-and-extension/ – bernie

+0

La estrella debería ser una ventaja, creo, aunque no está claro qué archivo llamado 'log'. debería regresar –

+1

Aunque esto funciona como se anuncia, ¿podría sugerir anteponer un "^" ancla solo por legibilidad? Sin el ancla, un programador que vea esta expresión regular por primera vez necesita realizar un análisis detallado para verificar que la coincidencia devuelta siempre comience al comienzo de la cadena. –

4

Todo seguido de un punto seguido de uno o más caracteres que no es un punto, seguido de la cadena de fin de:

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

El todo-antes-del-pasado-punto está agrupada para facilitar su recuperación.

Si no está 100% seguro de que cada archivo tendrá una extensión, intente:

(.+?)(\.[^\.]+$|$) 
+0

No coincide con un nombre de archivo que no tiene extensión –

3

¿qué hay de 2 capta una para el final y una para el nombre de archivo.

por ejemplo.

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

Eso está bien, pero como voy a descartar el nombre del archivo, ¿para qué molestarse? Me gustaría una expresión regular que solo obtiene el nombre del archivo. –

+0

Éste tampoco coincidirá con un nombre de archivo que no contenga ninguna extensión. –

0

Ok, no estoy seguro de por qué usaría la expresión regular para esto. Si sé, por ejemplo, que la cadena es una ruta de archivo completa, entonces usaría otra API para obtener el nombre del archivo. Las expresiones regulares son muy potentes, pero al mismo tiempo bastante complejas (acaba de demostrarlo al preguntar cómo crear una expresión regular tan simple). Alguien dijo: tenías un problema que decidiste resolver usando expresiones regulares. Ahora tienes dos problemas.

Piénselo de nuevo. Si está en la plataforma .NET, por ejemplo, eche un vistazo a la clase System.IO.Path.

+0

Bueno, eso no es muy divertido, ¿o sí? De todos modos, ajustó la pregunta a su respuesta, por favor vea arriba. Gracias. –

0
^(.*)\\(.*)(\..*)$ 
  1. Obtiene la ruta sin la última \
  2. El archivo sin extensión
  3. La extensión con un .

Ejemplos:

c:\1\2\3\Books.accdb
(c:\1\2\3)(Books)(.accdb)

no admite varios . en nombre de archivo ¿son compatibles con . en la ruta del archivo

0

utilicé este patrón de búsqueda simple:

^\s*[^\.\W]+$ 

para este texto:

file.ext 
    fileext 

    file.ext.ext 
file.ext 
fileext 

Encuentra fileext en la segunda y última línea.
Lo apliqué en una vista de árbol de texto de una carpeta (con espacios como sangrías).

Cuestiones relacionadas