Perl Regex - Print the matched value

/(\d+$)/;
print $1;

I guess you just want the number 195. Right?


How about just:

print $string =~ /Total Successful Transactions = (\d+)/;

You rarely actually need to use $1 and friends.


You can use parentheses in regex to capture substrings. The captured groups are stored in $1, $2, and so on. Example:

while (<>) {
    if (/Total Successful Transactions = (\d+)/) {
        print "$1\n";
    }
}

or, somewhat shorter:

while (<>) {
    print "$1\n" if /Total Successful Transactions = (\d+)/;
}

You can also make use of the fact that the match operator (//) in list context returns a list of what was matched by groups:

$\ = '\n'; # Output newline after each print.
while (<>) {
    print for /Total Successful Transactions = (\d+)/;
}

Which lets you write a compact one-liner (the -l option automatically adds newlines to each print, among other things):

perl -lne 'print for /Total Successful Transactions = (\d+)/'

Just wanted to reframe the previous answers a bit differently; note that in this case:

$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /Xy = 3/;'
1 

... we get 1 being printed out - as in "yes, I got a match". If we want to return the matched text portion, as @markusk pointed out, "use parentheses in regex to capture substrings":

$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /(Xy = 3)/;'
Xy = 3

However, note that you may have a problem concatenating strings with this idiom, when capturing:

$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /Xy = 3/ . "\n";' 
1 # OK
$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /(Xy = 3)/ . "\n";' 
1 # NOT OK

... so probably better to keep things separate in that case:

$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /(Xy = 3)/ ; print "\n";'
Xy = 3 # OK again

 

However, if we want to capture "something", say a digit - then, since we use parentheses, we automatically return just that match with this idiom (not the entire "searched for" string):

$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /Xy = (\d)/ ; \
print "\n";'
3

... thus, to capture the searched string in its entirety, we should wrap it again in parentheses:

$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /(Xy = (\d))/ ; \
print "\n";'
Xy = 33

.... but, we don't get what we expect, because now there are two matches, $1 and $2; and apparently the idiom "print $str =~ /.../" outputs all matches (in this case, "$1$2").

So to get just the searched string in this nested matches case, we now have to explicitly specify only $1:

$ perl -e '$str="the variable Xy = 3 in this case"; $str =~ /(Xy = (\d))/ ; \
print "$1 \n";'
Xy = 3 

EDIT oct 2013: Via Assign one of multiple regex matches to variable as Perl one-liner (dereference array?) - also this can be done for a one liner:

$ perl -e '$str="the variable Xy = 3 in this case"; \
print ( ( $str =~ /(Xy = (\d))/ )[1] ); print "\n";'
3

... however, note the need for a second enveloping set of parentheses for the print to work directly with the regex returned (anonymous?) array.

 

Finally, in a multiline context, make sure to first "slurp" the entire file/text into a single string; then use the /s (single line mode = newline is matched) and /g (global/multiple matches) - and finally, make sure the match expression is in a while loop, so as to iterate through all the matches:

$ echo "some data
IN
123
OUT
some more data
 is about to follow:
IN
256
OUT
done with data
out" | perl -e '$str = do { local $/; <> }; while ($str =~ /(IN(.*?)OUT)/sg) { print "$1\n"} '

IN
123
OUT
IN
256
OUT

Well, hope this helps someone,
Cheers!

Tags:

Regex

Perl