2010-10-27 5 views
1

J'ai une chaîne qui ressemble à: /somedir/ref/some-dir/foo.wordComment extraire une sous-chaîne de cette chaîne?

Comment pourrais-je extraire foo de la chaîne ci-dessus? La chaîne entière, y compris foo peut varier, cependant, la structure est toujours la même. Ce sera toujours les lettres entre la dernière barre oblique et le dernier point.

+0

En quoi la structure est-elle la même? Avez-vous besoin de capturer les _letters_ entre le dernier slash_ et le _last dot_, ou ..? – mfontani

+0

C'est exact, toujours les lettres entre la dernière barre oblique et le dernier point. – rplant23

+0

Génial! Merci à tous. – rplant23

Répondre

12

Il semble que vous essayez de trouver le nom de fichier (sans extension) à partir d'un chemin de fichier qualifié complet. Si tel est le cas, alors regarder dans le module de base File::Basename:

my $str = "/somedir/ref/some-dir/foo.word"; 
my($filename, $directory, $suffix) = fileparse($str, qr/\.[^.]*/); 

La méthode fileparse() prend deux arguments: la chaîne à analyser et le suffixe de fichier à supprimer. Si vous ne savez pas quel sera le suffixe du fichier, vous pouvez fournir une expression régulière. Dans ce cas, le suffixe correspond à une période suivie de zéro ou plusieurs caractères non-point.

Edit: Et si vous ne trouvez pas les noms de fichiers, et que vous voulez les lettres entre le dernier et le dernier /., essayez ceci:

my $str = "/somedir/ref/some-dir/foo.word"; 
my @elems1 = split '/', $str; 
my @elems2 = split '\.', $elems1[-1]; 
my $foo = $elems2[-2]; 

TIMTOWTDI! :-)

+0

vous voudrez peut-être joindre tout sauf le dernier élément de '@ elems2' plutôt que d'avoir juste la seconde pour durer. – flies

-1
my ($foo) = $str =~ m|/(\w+)[^/]+$|; 

Cela suppose que la partie "foo" peut contenir n'importe quel caractère "mot" (alphanumérique plus trait de soulignement).

+3

Ceci est incorrect et ne fonctionnera pas dans le cas de test donné. –

+0

Je l'ai vérifié avant de le poster.Cette commande affiche "foo": perl -le 'my $ str = "/somedir/ref/some-dir/foo.word"; mon ($ foo) = $ str = ~ m |/(\ w +) [^ /] + $ |; print $ foo ' – Sean

+1

Le mot à mettre en correspondance peut être n'importe quoi, donc \ w ne peut pas correspondre par exemple: 'foo-bar' –

0

essayer cette

s/.*\/([^.]*)\..*/$1/g 
0

Essayez

if ($str =~ /\/([^\/]+)\.[^\/]*?$/) { 
    $foo = $1; # This is the word 'foo' in your test case. 
} else { 
    die("Error matching string"); 
} 

démonstration (en utilisant Ruby, mais l'expression rationnelle est la même dans les deux langues): http://www.rubular.com/r/7FUeFFV4QI

Edit: Correction d'un bug

+0

Si $ str ne correspond pas à cette regex, vous allez assigner à $ foo ce que $ 1 était après la dernière correspondance regex réussie. – Sean

+0

Alors que vous avez certainement raison, est-ce que cela mérite vraiment une downvote? Fixé dans le message. –

+0

@Sean - Ce n'est pas un problème du tout, d'autant plus que nous ne connaissons pas la nature du problème OP. Peut-être que cela pourrait même être un comportement désirable, je sais que j'ai utilisé une situation similaire à celle-ci où je voulais en fait la valeur précédente lorsque l'actuelle a échoué. J'ai voté ceci pour son vote négatif. Aucune réponse valide/code devrait être vers le bas voté à mon humble avis. – gnomed

-1
$str =~ m/\/(\w+)\./ 

foo sera stocké dans la variable $ 1 spéciale en perl. Si vous le souhaitez dans une variable normale après l'avoir assigné.

$myvar = $1; 

Ceci est facilement la solution la plus simple répertoriée jusqu'à présent.

Ceci va extraire toute chaîne de caractères entre "/" et "." dans l'entrée. Ce sera toujours le mot que vous voulez, à moins qu'il y ait plusieurs périodes dans la chaîne à comparer. Mais je suppose "." sera seulement à la fin (comme sur une extension de fichier).

+0

Amélioration du style: éliminez complètement les variables d'effet secondaire et les cure-dents penchés. 'my ($ resultat) = $ str = ~ m {/ (\ w +) \.};' – daxim

+0

Curieux pourquoi quelqu'un descendrait le code parfaitement valide qui répond à la question avec précision. – gnomed

0
#!/usr/bin/perl 

use strict; use warnings; 

my $s = '/somedir/ref/some-dir/foo.word'; 

if (my ($x) = $s =~ m{/(\w+)\.\w+\z}) { 
    print "$x\n"; 
} 
Questions connexes