tags:

views:

86

answers:

4

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?

+7  A: 
$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;
Philip Potter
@Philip: thanks!
Lazer
Lazer is asking for a number, not just an integer. This regexp will drop `.`, `e` which may be used to form a float. Also `\d` is not just `[0-9]`, due to Unicode support in Perl: digits in others glyphs (such as indian) are valid. So your regexp will also accepts strings which are not numbers.
dolmen
@dolmen Lazer should be more specific, then. His example doesn't include decimals or exponentials, and I can't know for sure whether he wants to include them or not. You're correct about unicode variant script digits, though, I will edit.
Philip Potter
+9  A: 

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)
FM
this is also useful!
Lazer
+1. This has the advantage over my answer that it doesn't assume there is only one embedded number in the string.
Philip Potter
A: 

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).

Ziggy
Never use the value in `$1`, `$2`, etc unless you have first confirmed that your match was successful. Capture variable are only (re)set on a successful match, if `$s` in your example does not have any digits you will get the result of your last match.
Ven'Tatsu
+3  A: 

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.

Axeman
The best answer!
dolmen