2010-07-19 16 views
11

necesito obtener el nombre de archivo de la cadena de ruta del archivo. Por ejemplo, a partir de esta cadena \abc\def\filename.txt i necesidad de obtener filename.txtextraer nombre de archivo de la ruta

tratando de hacer esto con expresiones regulares:

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

pero me da un error. ¿Qué expresiones regulares debo usar para resolver esto?

+0

No hay razón para reemplazar los caracteres con nada usando preg_replace. Es más directo usar solo preg_match en su lugar. (Vea mi respuesta para saber cómo). –

Respuesta

33

se debe utilizar el nombre base función de su lugar:

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

edición: nota importante, es necesario use comillas simples cuando tenga barras diagonales inversas en sus cadenas, de lo contrario capa ellos apropiadamente.

nota: esto no lo hará trabajo:

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

porque usted es de hecho la variable $ ruta de archivo contiene:

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

otra edición: esta expresión regular también funciona ..

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

todo lo que estaba mal con su original era que tenía comillas dobles en lugar de solo, y la barra invertida necesita un doble escape (\\ en lugar de \).

+0

@nathan: Eso no funcionará, le dará 'abcilename.txt' – Sarfraz

+0

@sAc: Funciona perfectamente para mí. – casablanca

+0

@casablanca: esperemos que otros también prueben ese código :) Aunque parece que no funciona para mí. – Sarfraz

3

Esto debe hacerlo:

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

Resultado:

filename.txt 
+0

que no funcionará para la ruta de archivo '\ abc \ def \ filename.txt' devolverá' 'def \ filename.txt' – nathan

+0

@nathan: Creo que el problema estaba en' \\ ', funciona bien con/'en el camino. – Sarfraz

3

dos soluciones:

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

1: preg_match()

Ok, entonces el problema es que estás usando barras diagonales inversas. Debe asegurarse de que no utilice comillas dobles para definir su ruta de archivo, ya que la barra diagonal inversa se interpreta como una secuencia de escape. Use comillas simples

Además, con una expresión regular, que es mucho más sencilla de obtener un nombre de archivo al pasar de la parte posterior de la ruta hasta llegar a una barra invertida .... el truco es que una barra invertida es \\\\ .. here's why

último , no desea usar preg_replace.Acaba de encontrar el nombre de archivo con 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() con pathinfo()

Como otros han dicho, basename() es una buena opción. Otra opción, si hay alguna posibilidad de que también necesite el directorio u otra información de ruta más adelante en la línea, es usar pathinfo()

El problema es que tanto basename como pathinfo asumen barras diagonales, por lo que debe convertir sus barras invertidas para avanzar barras diagonales:

Ejemplo:

<?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

Eso tampoco funcionará, también necesita la solución de expresiones regulares como lo indicó. – Sarfraz

+0

@sAc pensé OP indicó que la expresión regular no estaba funcionando muy bien ... GTG, sino que tratará en unos –

+0

Funciona sólo cuando se utiliza una barra (/) en lugar de la barra invertida en el camino. +1 ahora :) – Sarfraz

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

¿por qué tirar de expresiones regulares en un problema tan simple?

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

EDITAR: No he probado esto - No tengo un servidor PHP que funcione a la mano. No podría ser un error de uno a uno con substr y strrpos, pero si ese es el caso, simplemente agrega o resta uno de $pos.

Edit2: He aquí una versión de la barra invertida:

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

OP tiene barras diagonales inversas, por lo que no puede duplicar $ source y tiene que escapar de la barra invertida en $ pos –

+0

@Peter: se agregó una barra diagonal inversa. –

Cuestiones relacionadas