0

I want to find all calls of a function in a source-file using perl and regex.

The function call looks (simplified) like:

gettrans(ABC,DEF,GHI);

The second and third parameter are optional. So gettrans(ABC) and gettrans(ABC,DEF) are also valid. But the function must have at least the first parameter.

I'm using the following testfile to check my perl-code:

gettrans(ABC);
gettrans(ABC,D);
gettrans(ABC,D,E);
gettrans(A,B,C);        gettrans(D);
gettrans(ABC,);
gettrans(,A);

My current perl-code looks as follows:

#!/usr/bin/perl -w
my $i = 1;
while ( my $line = <> ) {
    my @res = ( $line =~ /gettrans\((\w+)(,\w+){0,2}\)/g );

    print "line " . $i . ":\n";
    foreach (@res) {
        if ( defined($_) ) {
            print $_ . "\n";
        }
    }
    print "\n";
    $i++;
}

This gives the following output:

line 1:
ABC

line 2:
ABC
,D

line 3:
ABC
,E

line 4:
A
,C
D

line 5:

line 6:

However, what I expected as output or better, what I want to have is something like:

line 1:
gettrans(ABC)

line 2:
gettrans(ABC,D)

line 3:
gettrans(ABC,D,E)

line 4:
gettrans(A,B,C)
gettrans(D)

line 5:

line 6:

Additionally, what is also very confusing for me is, that if I replace the commas in the testfile and in the regular expression with a 0 (zero), I get a total different output, that comes closer to what I want (except the fact, that in this case I also get output for line 5 and line 6 [which are invalid functions calls]).

Output for replacing commas with 0 (zero):

line 1:
ABC

line 2:
ABC0D

line 3:
ABC0D0E

line 4:
A0B0C
D

line 5:
ABC0

line 6:
0A

I'm just started learning both pearl and regex. Would be nice to get any hints about the misunderstandings I have at the moment.

Thank you all!

cu, peter

1
  • About the comma/zero part: You're matching with \w+. \w is equivalent with [a-zA-Z0-9_], so those zeros simply get matched as if they are letters like your ABCD. Commented Oct 22, 2014 at 7:53

2 Answers 2

1

Wrap the entire regex in parenthesis as

(gettrans\(\w+(,\w){0,2}\);)

which would match the function calls

while (my $line = <>) {
        $line =~ /(gettrans\(\w+(,\w){0,2}\);)/g
        print $1 . "\n"
}

would produce output as

gettrans(ABC);
gettrans(ABC,D);
gettrans(ABC,D,E);
gettrans(A,B,C);        gettrans(D);

Here $line =~ /(gettrans\(\w+(,\w){0,2}\);)/g checks for the pattern in $line and the matches string within paranthesis () is saved in $1 variable, which is printed.

#!/usr/bin/perl -w
my $i = 1;
while (my $line = <>) {
        $line =~ /(gettrans\((\w+)(,\w+){0,2}\))/g;

        print "line " . $i . ":\n";
        
        print $1."\n";
        $i++;
}

will produce output as

line 1:
gettrans(ABC)

line 2:
gettrans(ABC,D)

line 3:
gettrans(ABC,D,E)

line 4:
gettrans(A,B,C)
gettrans(D)

line 5:

line 6:
Sign up to request clarification or add additional context in comments.

Comments

0

The following is how I would construct your regular expression.

Note, that the line number variable $. can display the current line number of the file handle last read from:

use strict;
use warnings;

while (<DATA>) {
    if ( my @results = /gettrans\(\w+(?:,\w+){0,2}\)/g ) {
        print "line $.:\n";
        print "$_\n" for @results;
        print "\n";
    }
}

__DATA__
gettrans(ABC);
gettrans(ABC,D);
gettrans(ABC,D,E);
gettrans(A,B,C);        gettrans(D);
gettrans(ABC,);
gettrans(,A);

Outputs:

line 1:
gettrans(ABC)

line 2:
gettrans(ABC,D)

line 3:
gettrans(ABC,D,E)

line 4:
gettrans(A,B,C)
gettrans(D)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.