Regex – In Perl, how can I get the matched substring from a regex

perlregex

My program read other programs source code and colect information about used SQL queries. I have problem with getting substring.

...
$line = <FILE_IN>;
until( ($line =~m/$values_string/i && $line !~m/$rem_string/i) || eof )
{
   if($line =~m/ \S{2}DT\S{3}/i)
   {

   # here I wish to get (only) substring that match to pattern \S{2}DT\S{3} 
   # (7 letter table name) and display it.
      $line =~/\S{2}DT\S{3}/i;
      print $line."\n";
...

In result print prints whole line and not a substring I expect. I tried different approach, but I use Perl seldom and probably make basic concept error. ( position of tablename in line is not fixed. Another problem is multiple occurrence i.e.[… SELECT * FROM AADTTAB, BBDTTAB, …] ). How can I obtain that substring?

Best Solution

Use grouping with parenthesis and store the first group.

if( $line =~ /(\S{2}DT\S{3})/i )
{
  my $substring = $1;
}

The code above fixes the immediate problem of pulling out the first table name. However, the question also asked how to pull out all the table names. So:

# FROM\s+     match FROM followed by one or more spaces
# (.+?)       match (non-greedy) and capture any character until...
# (?:x|y)     match x OR y - next 2 matches
# [^,]\s+[^,] match non-comma, 1 or more spaces, and non-comma
# \s*;        match 0 or more spaces followed by a semi colon
if( $line =~ /FROM\s+(.+?)(?:[^,]\s+[^,]|\s*;)/i )
{
  # $1 will be table1, table2, table3
  my @tables = split(/\s*,\s*/, $1);
  # delim is a space/comma
  foreach(@tables)
  {
     # $_ = table name
     print $_ . "\n";
  }
}

Result:

If $line = "SELECT * FROM AADTTAB, BBDTTAB;"

Output:

AADTTAB
BBDTTAB

If $line = "SELECT * FROM AADTTAB;"

Output:

AADTTAB

Perl Version: v5.10.0 built for MSWin32-x86-multi-thread