2009-05-13 6 views
1

HI,
J'ai une chaîne qui ressemble àComment remplacer une partie d'une chaîne à l'aide de regexp?

/dir/dir1/filename.txt 

Je veux remplacer le « filename.txt » avec un autre nom laissant intact «/dir/dir1 » donc après le remplacement de la chaîne ressemblerait

/dir/dir1/newfilename.txt 

comment pourrais-je faire en utilisant RegExp en Perl étant donné que je ne connais pas la valeur de « nom de fichier »

Merci beaucoupP.S: "filename.txt" et "newfilename.txt" ont été utilisés dans le but de simplifier les choses en posant la question que le nom de fichier original variera.

Répondre

7
$filename =~ s%/[^/]*$%/newfilename.txt%; 
  • s%...%...% - utiliser % comme séparateur, de sorte que vous pouvez utiliser / dans le modèle
  • / - correspondre à une barre oblique
  • [^/]* - et toute chaîne ne contenant pas une barre oblique
  • $ - jusqu'à la fin de la chaîne
+0

@Alnitak Merci beaucoup pour votre réponse, une chose s'il vous plaît, si je voulais juste extraire « filename.txt » de « /dir/dir1/filename.txt » au lieu de le remplacer , qu'est-ce que j'utiliserais dans l'expression rationnelle –

+0

"if ($ filename = ~ m% ...%)" et envelopper le bit [^ /] * d'origine avec des parenthèses {i.e. ([^ /] *)} et ensuite il sera disponible en $ 1 – Alnitak

11

Je suggère de ne pas utiliser d'expressions régulières pour jouer avec les noms de fichiers/chemins. Les séparateurs de répertoire, les caractères valides/non valides varient d'une plateforme à l'autre et peuvent être un problème à traquer. Je vous conseille d'essayer File::Spec pour extraire le nom de fichier et ensuite le remplacer par ce que vous voulez

10

Les expressions régulières sont l'outil incorrect pour votre problème. Les regex sont fantastiques, fonctionnent la plupart du temps mais ne sont pas toujours les plus propres (lisibilité) ou la solution la plus rapide. Je voudrais proposer d'utiliser le File::Basename classique. En contraste avec fichier :: Spec, File :: Basename est un module de base (rien à installer!) Et vraiment facile à utiliser:

use File::Basename; 

    my $basename = basename($fullname,@suffixlist); 
    my $dirname = dirname($fullname); 

Mon utilisation préférée:

my $filename = basename($path); 
1

Essayez quelque chose comme ça ...

#!/usr/bin/perl 

use strict; 

my $string = "/dir/dir1/filename.txt"; 
my @string = split /\//, $string; 
$string[-1] = "newfilename.txt"; 
print join "/", @string; 
Questions connexes