Perl and Regex - single line mode matching

1.8k views Asked by At

Why doesn't

perl -ne "print if /(<Conn)([\S|\s]+?)(>)/sg;" /path/to/file

match

<Connector port="PORT" protocol="HTTP/1.1" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS" />`

when it does match

<Connector port="PORT" protocol="AJP/1.3" redirectPort="PORT" />

And what would I need to do to match both with the same regex?

2

There are 2 answers

4
kjpires On BEST ANSWER

The -n option reads the file line-by-line, but you can alter what a line is to be the whole file by undefining the input line terminator. That's is done using local $/;, or using the command line option -0777 as follows:

perl -0777ne 'print "$1\n" while /(<Conn.+?>)/sg;' /path/to/file

It reads in the whole file at once. If that's a problem, try setting $/ to > (since your pattern always ends in >) or -o076 on the command-line:

perl -076ne 'print "$1\n" if /(<Conn.+?>)/sg;' /path/to/file
0
zgpmax On

Because it is running line-wise. On your first data, $_ will take on three separate values

  1. <Connector port="PORT" protocol="HTTP/1.1" SSLEnabled="true"
    
  2. maxThreads="150" scheme="https" secure="true"
    
  3. clientAuth="false" sslProtocol="TLS" />
    

and none of these will match on their own.

If you want to make it match, perhaps you could try slurping the whole file.

my $whole_file = do { local $/; <> };