2009-11-30 5 views
25

J'ai besoin d'une expression régulière qui peut supprimer l'extension d'un nom de fichier, renvoyant uniquement le nom du fichier.Expression régulière pour supprimer l'extension d'un fichier

Voici quelques exemples d'entrées et de sorties:

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

Je ne peux évidemment le faire manuellement (c.-à enlever tout à partir du dernier point), mais je suis sûr qu'il ya une expression régulière qui peut le faire par lui-même.

Pour la petite histoire, je le fais en JavaScript

Répondre

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

Le résultat sera dans ce premier groupe de capture. Cependant, il est probablement plus efficace de simplement trouver la position de la période la plus à droite et ensuite de tout prendre avant, sans utiliser regex.

+0

Pensez également à des choses comme 'a.longthingrighthereattheend' ou' .ext' & 'file.'. Peut-être vérifier avec '/ (. *) \. [^.] {1,10} $ /'. En fait, utilisez simplement 'pathinfo()'. – Xeoncross

+0

Une solution presque parfaite mais, si vous voulez éviter le piège de noms de fichiers comme .htaccess (commence avec une période, mais n'a pas d'extension), comme Roger Pate, il suffit de remplacer le premier astérisque par un signal plus, comme suit: (. +) \. [^.] + $ – aldemarcalazans

4

L'expression régulière pour correspondre au modèle est:

/\.[^.]*$/ 

Il trouve un caractère de période (. \), suivi de 0 ou plusieurs caractères qui ne sont pas des périodes ([^.] *), suivi de la fin de la chaîne ().

+1

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

+0

Cette regex retourne l'extension, alors que j'ai besoin d'enlever l'extension –

+0

lire la question pls – mahatmanich

-2

En JavaScript, vous pouvez appeler la méthode Replace() qui remplacera en fonction d'une expression régulière.

Cette expression régulière correspond à tout depuis le début de la ligne jusqu'à la fin et supprime tout ce qui suit la dernière période, y compris la période.

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

La façon de mettre en œuvre le remplacement peut être trouvée dans cette question Stackoverflow.

Javascript regex question

+0

En fait, comme vous l'avez actuellement écrit, il supprimera tout ce qui suit * * période, puisque votre groupe de capture est défini comme non gourmand, et que votre dernier '. *' peut correspondre à n'importe quel élément, y compris les périodes. – Amber

+0

Ouais je me suis rendu compte qu'après l'avoir posté et ensuite mis à jour. Merci – Tinidian

+0

@Amber Qu'est-ce qui rend son groupe de capture non gourmand? Je pensais. * Est toujours gourmand. . *? serait paresseux. Et ce modèle semble fonctionner^(. *) \ .. * $ – barlop

68

Juste pour être complet: Comment cela pourrait-il être réalisé sans expressions régulières?

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

Le || input prend en charge le cas où lastIndexOf() fournit un -1. Vous voyez, c'est toujours un one-liner.

+3

Je l'ai beaucoup aimé ce que vous avez fait avec entrée/sortie! :) –

+1

Belle solution! J'ai eu tunnelvision sur RegEx, mais cela fonctionne aussi – Jareish

+0

De même, en utilisant [underscore.string] (https://github.com/epeli/underscore.string): 'var output = _s.strLeftBack (entrée, '.'); // 'myfile'' –

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

cas de test où cela fonctionne et d'autres ne parviennent:

  • ".htaccess" (période qui a précédé)
  • "fichier" (pas d'extension de fichier)
  • "Envoyer à mrs." (Pas d'extension, mais se termine par Abr.)
  • "version 1.2 du projet" (pas d'extension, mais contient encore une période)

Le fil rouge ci-dessus est, bien sûr, les extensions de fichier "malformés". Mais vous devez toujours penser à ces cas de coin.: P

cas de test où cela ne parvient:

  • "version 1.2" (pas d'extension de fichier, mais "semble" avoir un)
  • "name.tar.gz" (si vous affichez cette comme une "extension composée" et voulait le diviser en "nom" et ".tar.gz")

Comment gérer ces est problématique et mieux décidé sur une base de projet spécifique.

0

Cela fera aussi bien :)

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

je bâton à la regexp si ... = P

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

modèle Au-dessus est faux - il inclura toujours l'extension aussi. C'est à cause du fonctionnement du moteur de javascript regex. Le jeton est (\.[^ .]+) en option si le moteur correspondra avec succès la chaîne entière avec (.+) http://cl.ly/image/3G1I3h3M2Q0M


Voici ma solution regexp testé.

Le modèle correspondra filenameNoExt avec/sans extension dans le chemin, en respectant les slash et les séparateurs de barre oblique inverse

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

de dissection du motif ci-dessus:

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

Cela couvrira tous les cas qui ont été mentionnés par @RogerPate mais y compris les chemins complets aussi

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

il fera de votre souhait. Mais pas d'expression régulière.

+2

Ceci est faux, il retournera l'extension de fichier et non le nom de fichier, qui a été demandé dans la question. –

+0

Vous pouvez utiliser shift() au lieu de pop(). – simonox

1

autre aucun moyen regex de le faire le « oposite » ou la version de raul (ne pas utiliser pop() pour supprimer)

Il fait, il est donc pas besoin de soumettre à la variable deux fois plus facile à inline

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