KittenCodings
KittenCodings

Reputation: 585

Regex Match Exact Number at beginning (like 99 but not 999)

This should be a simple task, but searching for it all day I still can't figure out what I'm missing

I'm trying to open a file using PHP's glob() that begins with a specific number

Example filenames in a directory:

1.txt
123.txt
10 some text.txt
100 Some Other Text.txt

The filenames always begin with a unique number (which is what i need to use to find the right file) and are optionally followed by a space and some text and finally the .txt extension

My problem is that no matter what I do, if i try to match the number 1 in the example folder above it will match every file that begins with 1, but I need to open only the file that starts with exactly 1, no matter what follows it, whether it be a space and text or just .txt

Some example regex that does not succeed at the task:

filepath/($number)*.txt
filepath/([($number)])( |*.?)*.txt
filepath/($number)( |*.?)*.txt

I'm sure there's a very simple solution to this... If possible I'd like to avoid loading every single file into a PHP array and using PHP to check every item for the one that begins with only the exact number, when surely regex can do it in a single action

A bonus would be if you also know how to turn the optional text between the number and the extension into a variable, but that is entirely optional as it's my next task after I figure this one out

Upvotes: 1

Views: 1176

Answers (4)

Mordred
Mordred

Reputation: 3941

The Regex you want to use is: ^99(\D+\.txt)$

$re = "/^99(\D+\.txt)$/";
preg_match($re, $str, $matches);

This will match:

99.txt
99files.txt

but not:

199.txt
999.txt
99
99.txt.xml
99filesoftxt.dat

The ( ) around the \D+.txt will create a capturing group which will contain your file name.

Upvotes: 2

Federico Piazza
Federico Piazza

Reputation: 30995

You can use a regex like this:

^10\D.*txt$
  ^--- use the number you want

Working demo

enter image description here

For intance:

$re = "/^10\\D.*txt$/m"; 
$str = "1.txt\n123.txt\n10 some text2.txt\n100 Some Other2 Text.txt"; 

preg_match_all($re, $str, $matches);
// will match only 10 some text.txt

Upvotes: 1

Sean Bright
Sean Bright

Reputation: 120644

Here you go:

<?php
    function findFileWithNumericPrefix($filepath, $prefix)
    {   
        if (($dir = opendir($filepath)) === false) {
            return false;
        }

        while (($filename = readdir($dir)) !== false) {
            if (preg_match("/^$prefix\D/", $filename) === 1) {
                closedir($dir);
                return $filename;
            }
        }

        closedir($dir);

        return false;
    }

    $file = findFileWithNumericPrefix('/base/file/path', 1);                

    if ($file !== false) {
        echo "Found file: $file";
    }
?>

With your example directory listing, the result is:

Found file: 1.txt

Upvotes: 1

James G.
James G.

Reputation: 2904

I believe this is what you want OP:

$regex = '/' . $number . '[^0-9][\S\s]+/';

This matches the number, then any character that isn't a number, then any other characters. If the number is 1, this would match:

1.txt
1abc.txt
1 abc.txt
1_abc.txt
1qrx.txt

But it would not match:

1
12.txt
2.txt
11.txt
1.

Upvotes: 1

Related Questions