mobilestimulus
mobilestimulus

Reputation: 180

Parse filename with extension to isolate leading characters and numeric suffix without the extension

My current code:

$path2 = $file_list1; 
$dir_handle2 = @opendir($path2) or die("Unable to open $path2"); 
while ($file2 = readdir($dir_handle2)) { 
if ($file2 == "." || $file2 == ".." || $file2 == "index.php" ) 
    continue; 
echo '' . $file2 . '<br />'; 
} 
closedir($dir_handle2);
echo '<br />';

When $file2 is returned, the end of the string will always be a number plus the file extension .txt, like this:

file_name_here1.txt
some_other-file10.txt

So my question is, how can I separate $file2 so it returns the string in two parts, $file_name and $call_number like this?:

echo 'File: ' . $file_name . ' Call: ' . $call_number . '<br />';

Returns:

File: file_name_here Call: 1
File: some_other-file Call: 10

instead of this:

echo '' . $file2 . '<br />';

Returns:

file_name_here1.txt
some_other-file10.txt

Late edit:

Suppose filenames occur as file_name_1__123.txt and this_file_name_2__456.txt where the ending is always 2 [underscores][call#].txt. How do I get the call number then?

Upvotes: 1

Views: 516

Answers (5)

mickmackusa
mickmackusa

Reputation: 48049

Lazily match the leading characters in the filename, then match the latest occurring integer value before the extension.

Code: (Demo)

$tests = [
    'file_name_here1.txt',
    'some_other-file10.txt',
    'file_name_1__123.txt',
    'this_file_name_2__456.txt',
];

foreach ($tests as $test) {
    preg_match('/(.+?)(\d+)\.\w+$/', $test, $m);
    var_dump(array_slice($m, 1));
}

Output:

array(2) {
  [0]=>
  string(14) "file_name_here"
  [1]=>
  string(1) "1"
}
array(2) {
  [0]=>
  string(15) "some_other-file"
  [1]=>
  string(2) "10"
}
array(2) {
  [0]=>
  string(13) "file_name_1__"
  [1]=>
  string(3) "123"
}
array(2) {
  [0]=>
  string(18) "this_file_name_2__"
  [1]=>
  string(3) "456"
}

Upvotes: 0

Crozin
Crozin

Reputation: 44396

  1. Use pathinfo() function to cut off file extension.
  2. Use preg_match() function to separate name from number. 3.

    while (...) {
        ...
    
        $filename; // some_other-file10.txt
        $filename = pathinfo($filename, PATHINFO_FILENAME); // some_other-file10
        preg_match('/^(?<name>.*?)(?<number>\d+)$/', $filename, $match);
    
        $match['name'];   // some_other-file
        $match['number']; // 10
    
        echo "File: {$match['name']} Call: {$match['number']}\n";
    }
    

Upvotes: 0

Jake N
Jake N

Reputation: 10583

Try this, you need to use Regex to do this effectively

$filename = reset(explode(".", $file2))
preg_match("#(^[a-zA-Z\_\-]*)([\d]*)#", $filename, $matches);
$fullMatch = $matches[0];
$file = $matches[1];
$call = $matches[2];

echo "File: " . $file . " Call: " . $call;

Upvotes: 1

Aaron Hathaway
Aaron Hathaway

Reputation: 4315

I'm a big advocate of Regex but I decided to go slightly different here. Check it out:

$file = 'file_name_here19.txt';
$file_parts = pathinfo($file);
$name = $file_parts['filename'];
$call = '';
$char = substr($name, strlen($name) - 1);
while(ord($char) >= 48 && ord($char) <= 57) {
    $call = $char . $call;
    $name = substr($name, 0, strlen($name) - 1);
    $char = substr($name, strlen($name) - 1);
}
echo 'Name: ' . $name . ' Call: ' . $call;

Upvotes: 1

yscik
yscik

Reputation: 879

Use regular expressions:

preg_match("/^(.+)(\d+)(\..+)$/", $file2, $matches);
$file_name = $matches[1];
$call_number = $matches[2];

Upvotes: 1

Related Questions