Perl regex in order to have only digits from a basename file [duplicate]

I have

print $str;
abcd*%1234$sdfsd..#d

The string would always have only one continuous stretch of numbers, like 1234 in this case. Rest all will be either alphabets or other special characters.

How can I extract the number (1234 in this case) and store it back in str?

This page suggests that I should use \d, but how?


Solution 1:

If you don't want to modify the original string, you can extract the numbers by capturing them in the regex, using subpatterns. In list context, a regular expression returns the matches defined in the subpatterns.

my $str = 'abc 123 x456xy 789foo';

my ($first_num) = $str =~ /(\d+)/;   # 123
my @all_nums    = $str =~ /(\d+)/g;  # (123, 456, 789)

Solution 2:

$str =~ s/\D//g;

This removes all nondigit characters from the string. That's all that you need to do.

EDIT: if Unicode digits in other scripts may be present, a better solution is:

$str =~ s/[^0-9]//g;

Solution 3:

If you wanted to do it the destructive way, this is the fastest way to do it.

$str =~ tr/0-9//cd;

translate all characters in the complement of 0-9 to nothing, delete them.

The one caveat to this approach, and Phillip Potter's, is that were there another group of digits further down the string, they would be concatenated with the first group of digits. So it's not clear that you would want to do this.

The surefire way to get one and only one group of digits is

( $str ) = $str =~ /(\d+)/;

The match, in a list context returns a list of captures. The parens around $str are simply to put the expression in a list context and assign the first capture to $str.

Solution 4:

Personally, I would do it like this:

$s =~ /([0-9]+)/; 
print $1;

$1 will contain the first group matched the given regular expression (the part in round brackets).