David Wright
David Wright

Reputation: 435

Regex to Capture Specific 8-digit String in Variable using Perl

In my Perl script, I have a variable that contains a specific file path. I need to create a regular expression that can capture a specific 8-digit string from that variable.

When $file_path = "/home/attachments/00883227/sample.txt I want to capture the string of numbers immediately following "attachments".

My (unsuccessful) attempt:

if($file_path =~ /attachments\/(\d{1,2,3,4,5,6,7,8}+)/)
    { $number = $1; }

When I run this script, though, it looks like nothing is stored in the $number variable. The solution for this is probably very simple? Please pardon my ignorance, I am very new to Perl.

Upvotes: 1

Views: 2766

Answers (8)

Alan Alexander
Alan Alexander

Reputation: 61

Simply give the limits.

like, \d{3,8} where it will return digits between 3-8 length.

Upvotes: 1

ikegami
ikegami

Reputation: 385565

my ($number) = $file_path =~ m{attachments/(\d+)};

If you want to ensure it's exactly eight digits long,

my ($number) = $file_path =~ m{attachments/(\d{8})(?!\d)};

Upvotes: 1

David W.
David W.

Reputation: 107040

Is it going to be exactly 8 digits or between 1 to 8 digits?

Since you're looking at /attachments/ as a piece of the string, you probably don't want to use the standard /../ delimiters. Maybe switching to m{..} or m#..#:

if ( $file_path =~ m#/attachments/\(d{1,8})/# ) {

That will capture between 1 to 8 digits. To capture exactly 8:

my $number;
if ( $file_path =~ m#/attachments/(\d{8})/# ) {
   $number = $1;
   ...
}
else {
    ....
}

Note that I define $digit_string before the if statement. This way, it's in scope after the if statement (and inside the if statement. (You are using use strict;? Right?)

Upvotes: 0

Sinan Ünür
Sinan Ünür

Reputation: 118118

my ($number) = ( $file_path =~ m{ (attachments/( [0-9]{8} ) }x );

Using pattern delimiters other than / such as m{ }, you avoid the so-called leaning toothpick syndrome caused by the need to escape and / characters that appear in the pattern.

By assigning to $number in list context, the captured substring goes into $number immediately.

By using the x option, you make your pattern somewhat more readable.

Upvotes: 3

Qtax
Qtax

Reputation: 33908

Close, just use (\d{8}), like:

$file_path =~ /attachments\/(\d{8})\b/

Also added \b so that it doesn't capture any longer numbers.

Upvotes: 5

Rohit Jain
Rohit Jain

Reputation: 213203

You don't need to give so much of numbers in the braces. Simply use {8} to enforce matching of 8 digits. And since you have / inside your string, you can use a different delimiter, instead of escaping the slashes:

if($file_path =~ m!attachments/(\d{8})!)
   { $number = $1; }

Upvotes: 5

Jerry
Jerry

Reputation: 71538

Try using:

if($file_path =~ /attachments\/(\d+)/)
{ $number = $1; }

{ , } is used to limit the number of times a certain character (or group of characters) to repeat. {n,m} means that the character (or group) should repeat at least n times and at most m times.

If you're certain the string of digits is 8-digits long, you then use:

if($file_path =~ /attachments\/(\d{8})/)
{ $number = $1; }

{ } (without commas) will match exactly the number specified.

Upvotes: 1

Barmar
Barmar

Reputation: 780724

If you want to match exactly 8 digits, just use \d{8}:

if($file_path =~ /attachments\/(\d{8})/)
    { $number = $1; }

Upvotes: 3

Related Questions