How can I match the end of a line several times in a regular expression without interpolation?

if I have input with new lines in it, for example:

[INFO]
xyz
[INFO]

How can I pull out a piece of xyz with anchors $? I tried a type template /^\[INFO\]$(.*?)$\[INFO\]/ms, but perl gives me:

Use of uninitialized value $\ in regexp compilation at scripts\t.pl line 6.

Is there a way to disable interpolation so that the anchors work as expected?

EDIT: The key is that end-of-line binding is a dollar sign, but sometimes you may need to interpolate end-of-line binding through a pattern. If the template is interpolated, then problems can occur, such as uninitialized $\. For example, an acceptable solution here /^\[INFO\]\s*^(.*?)\s*^\[INFO\]/ms, but it does not solve the essence of the first problem. I changed the anchors to ^, so there is no interpolation, and with this input I can do it. But what about when I really want to reference EOL with help $in my template? How to get a regex for compilation?

+3
source share
5 answers

- $ . \n , $ .

EDIT: , $ . , , - . :

/^\[INFO\]$(.*?)$\[INFO\]/ms

, (.*?) , \nxyz, $ . - , [, . (.*?) - , $ .

, EOL $, , "", , , ? Perl regex $\ : , , .

+4

perlfaq6 - , ?, :

perl -0777 -ne 'print $1,"\n" while /\[INFO\]\s*(.*?)\s*\[INFO\]/sg' file.txt

-0777 .

, , , , File::Slurp :

use strict;
use warnings;
use File::Slurp qw/slurp/;

sub extract {

    my ( $tag, $fileName ) = @_;
    my $text = slurp $fileName;

    my ($info) = $text =~ /$tag\s*(.*?)\s*$tag/sg;
    return $info;
}

# Usage:
extract ( qr/\[INFO\]/, 'file.txt' );
+4

, , , . -- . , , , . , , , :

my $string = <<'HERE';
[INFO]
xyz
[INFO]
HERE

open my $string_fh, '<', \$string;

while( <$string_fh> )
    {
    next if /\[INFO]/ .. /\[INFO]/;
    chomp;

    print "Extracted <$_>\n";
    }

Perl 5.10, , \R :

use 5.010;

my $string = <<'HERE';
[INFO]
xyz
[INFO]
HERE

my( $extracted ) = $string =~ /(?:\A|\R)\[INFO]\R(.*?)\R\[INFO]\R/;

print "Extracted <$extracted>\n";

.

+4

, /x :

m/ ^\[INFO\] $ # Match INFO line
   \n
   ^ (.*?) $ # Collect desired line
   \n 
   ^ \[INFO\] # Match another INFO line
/xms

, , , . , $ .

+1

, ( , ). , . Perl script , Perl $ , - , $ EOL.

use strict;
use warnings;

my $x = "[INFO]\nxyz\n[INFO]";
if( $x =~ /^\[INFO\]$\n(.*?)$\n\[INFO\]/m ) {
    print "'$1' FOUND\n";
} else {
    print "NO MATCH FOUND\n";
}

if( $x =~ m'^\[INFO\]$\n(.*?)$\n\[INFO\]'m ) {
    print "'$1' FOUND\n";
} else {
    print "NO MATCH FOUND\n";
}

if( $x =~ m/ ^\[INFO\] $ # Match INFO line
\n
^ (.*?) $ # Collect desired line
\n 
^ \[INFO\] # Match another INFO line
/xms ) {
    print "'$1' FOUND\n";
} else {
    print "NO MATCH FOUND\n";
}

script :

Use of uninitialized value $\ in regexp compilation at t.pl line 5.
Use of uninitialized value $\ in regexp compilation at t.pl line 5.
NO MATCH FOUND
'xyz' FOUND
'xyz' FOUND
+1

Source: https://habr.com/ru/post/1746443/


All Articles