tags:

views:

104

answers:

5

i need to get filename from file path string. For example, from this string \abc\def\filename.txt i need to get filename.txt

trying to do this with regexp:

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

but it gives me an error. What regex i should use to solve this?

+3  A: 

This should do it:

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

Result:

filename.txt
Sarfraz
@sAc that won't work for the filepath `\abc\def\filename.txt` it'll return '`def\filename.txt`
nathan
@nathan: I believe problem was in `\\`, it works fine with /` in the path.
Sarfraz
@sAc nice fix +1 ;)
nathan
+7  A: 

you should use the function basename instead:

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

edit: important note, you need to use single quotes when you have backslashes in your strings, else delimit them properly.

note: this will not work:

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

because you're variable $filepath infact holds:

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

another edit: this regex works too..

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

all that was wrong with your original was that you had double-quotes rather than single, and backslash needs double escaped (\\ rather than \).

nathan
@nathan: That won't work, it will give you `abcilename.txt`
Sarfraz
@sAc: It works perfectly for me.
casablanca
@casablanca: Let's hope if others also try that code :) Doesn't seem to work for me though.
Sarfraz
@nathan: I believe problem was in `\\`, the basename worked fine with `/` in the path.
Sarfraz
@sAc good fix on your q, also the fix for basename is in the edit now - confused us for a minute there!
nathan
@nathan: yes because op was using back slash +1 anyways ;)
Sarfraz
FYI: `\f` should be formfeed.
Billy ONeal
@Billy: I thought so too, but surprisingly, PHP doesn't seem to interpret `\f`.
casablanca
+2  A: 

Two solutions:

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

1: preg_match()

Ok, so the problem is that you are using backslashes. You have to make sure that you do not use double quotes for defining your filepath, since the backslash is interpreted as an escape sequence. Use single quotes.

Additionally, with a regex, it's much simple to get a filename by moving from the back of the path until you hit a backslash.... the trick is that a backslash is \\\\.. here's why

Finally, you don't want to use preg_replace. Just find the filename with 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() with pathinfo()

As others said, basename() is a good option. Another option, if there's any chance that you may also need the directory or other path information later down the line is to use pathinfo()

The problem is that both basename and pathinfo assume forward slashes, so you must convert your backslashes to forward slashes:

Example:

<?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
?>
Peter Ajtai
@Peter Ajtai: That won't work either, also he needs regex solution as indicated by him.
Sarfraz
@sAc I thought OP indicated that regex wasn't working very well... gtg but will try in a few
Peter Ajtai
@Peter Ajtai: It works only when you use a slash (/) rather than backslash in the path. +1 now :)
Sarfraz
@sAc Thanks for the heads up. I rewrote the code using a pretty simple regex that just gets all characters from the back of the path that aren't a backslash. Also, fixed the original code with slash replace.
Peter Ajtai
A: 
preg_replace("/[^\/]+.([^\.]+\.[a-z]{3,5})/i","$1","abc/filename.txt"); //return filename.txt
Jet
A: 

Why throw regex at such a simple problem?

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

EDIT: I have not tried this -- I don't have a working PHP server handy. There might be an off-by-one error with substr and strrpos, but if that's the case you just add or subtract one from $pos.

EDIT2: Here's a backslash version:

$source = "\\i\\am\\a\\path.txt";
$pos = strrpos($source, '\\');
$result = substr($source, $pos === FALSE ? 0 : $pos);
Billy ONeal
@Billy OP has backslashes, so you can't double quote $source and you have to escape the backslash in $pos
Peter Ajtai
@Peter: Added a backslash version.
Billy ONeal