2010-07-19 7 views
11

J'ai besoin d'obtenir le nom du fichier à partir de la chaîne de chemin du fichier. Par exemple, à partir de cette chaîne \abc\def\filename.txt je dois obtenir filename.txtextrait le nom de fichier du chemin

essayer de le faire avec regexp:

$filepath="abc\filename.txt"; 
$filename = preg_replace("/.+\\/","",$filepath); 

mais il me donne une erreur. Quel regex je devrais utiliser pour résoudre ceci?

+0

Il n'y a aucune raison de remplacer les caractères avec rien en utilisant preg_replace. Il est plus direct d'utiliser simplement preg_match à la place. (Voir ma réponse pour comment). –

Répondre

33

vous devez utiliser la fonction basename à la place:

$filepath = 'abc\filename.txt'; 
$filename = basename($filepath); 

modifier: note importante, vous devez utilisez des guillemets simples lorsque vous avez des antislashs dans vos ficelles, sinon les cape correctement.

Note: cette ne sera pas travail:

$filepath = "abc\filename.txt"; 
$filename = basename($filepath); 

parce que vous êtes enfait variable filepath de $ détient:

abc[special char here equalling \f]ilename.txt

une autre édition: ce regex fonctionne aussi ..

$filepath = '\def\abc\filename.txt'; 
$basename = preg_replace('/^.+\\\\/', '', $filepath); 

tout ce qui n'allait pas avec votre original était que vous aviez des guillemets doubles plutôt que des simples, et que le backslash avait besoin de double échappement (\\ plutôt que \).

+0

@nathan: Cela ne fonctionnera pas, il vous donnera 'abcilename.txt' – Sarfraz

+0

@sAc: Cela fonctionne parfaitement pour moi. – casablanca

+0

@casablanca: Espérons que d'autres personnes essaient aussi ce code :) Cela ne semble pas fonctionner pour moi. – Sarfraz

3

Cela devrait le faire:

$filepath='abc\filename.txt'; 
$basename = preg_replace('/^.+[\\\\\\/]/', '', $filepath); 
echo $basename; 

Résultat:

filename.txt 
+0

qui ne fonctionnera pas pour le chemin de fichier '\ abc \ def \ filename.txt' il retournera' 'def \ filename.txt' – nathan

+0

@nathan: Je crois que le problème était dans' \\ ', ça marche bien avec/'Dans le chemin. – Sarfraz

3

Deux solutions:

  1. preg_match()
  2. str_replace() avec pathinfo()

1: preg_match()

Ok, le problème est que vous utilisez des barres obliques inverses. Vous devez vous assurer que vous n'utilisez pas les guillemets pour définir votre chemin de fichier, puisque la barre oblique inverse est interprétée comme une séquence d'échappement. Utilisez des guillemets simples.

De plus, avec une expression régulière, il est beaucoup plus simple d'obtenir un nom de fichier en déplaçant à l'arrière du chemin jusqu'à ce que vous frappez une barre oblique inverse .... le truc est que une barre oblique inverse est \\\\ .. here's why

Enfin , vous ne voulez pas utiliser preg_replace.Il suffit de trouver le nom du fichier avec preg_match:

<?php 
    // Use single quotes or the backslash will be interpreted as an esacpe sequence 
$filepath = '\abc\def\filename.txt'; 

    // You have to use 4 backslashes to represent your single backslash 
    // The regex picks the characters that are NOT \ from the end of the path 
$pattern = '/[^\\\\]+$/'; 

    // Use $matches to store the match 
preg_match($pattern, $filepath, $matches); 

    // Display answer now, or use later 
echo $matches[0]; 
?> 

2: str_replace() avec pathinfo()

Comme d'autres ont dit, basename() est une bonne option. Une autre option, si vous avez besoin du répertoire ou d'autres informations de chemin plus tard, est d'utiliser pathinfo()

Le problème est que les deux basename et pathinfo supposent des barres obliques, donc vous devez convertir vos antislashs vers l'avant barres obliques:

Exemple:

<?php 
    // Make sure to use single quotes 
$filepath='abc\filename.txt'; 
    // Replace backslash with forward slash 
$filepath = str_replace('\\', '/', $filepath); 
$path_parts = pathinfo($filepath); 

    // This is the answer you want 
echo $path_parts['basename'], "\n"; 

    // But you also have access to these 
echo $path_parts['dirname'], "\n"; 
echo $path_parts['extension'], "\n"; 
echo $path_parts['filename'], "\n"; // since PHP 5.2.0 
?> 
+0

Cela ne fonctionnera pas non plus, aussi il a besoin de la solution regex comme indiqué par lui. – Sarfraz

+0

@sAc Je pensais OP a indiqué que regex ne fonctionnait pas très bien ... gtg mais va essayer dans quelques –

+0

Cela fonctionne uniquement lorsque vous utilisez une barre oblique (/) plutôt que backslash dans le chemin. +1 maintenant :) – Sarfraz

1
preg_replace("/[^\/]+.([^\.]+\.[a-z]{3,5})/i","$1","abc/filename.txt"); //return filename.txt 
0

Pourquoi jeter à un regex simple problème?

$source = "/i/am/a/path.txt"; 
$pos = strrpos($source, '/'); 
$result = substr($source, $pos === FALSE ? 0 : $pos); 

EDIT: Je n'ai pas essayé - je n'ai pas de serveur PHP fonctionnel à portée de main. Il pourrait être une erreur off-by-one avec substr et strrpos, mais si c'est le cas, il suffit d'ajouter ou de soustraire un de $pos.

EDIT2: Voici une version backslash:

$source = "\\i\\am\\a\\path.txt"; 
$pos = strrpos($source, '\\'); 
$result = substr($source, $pos === FALSE ? 0 : $pos); 
+1

OP a backslashes, donc vous ne pouvez pas double quote $ source et vous devez échapper à la barre oblique inverse dans $ pos –

+0

@Peter: Ajout d'une version backslash. –

Questions connexes