Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Multiline replace regexp.

by nikolay (Beadle)
on May 21, 2018 at 12:47 UTC ( [id://1214971]=perlquestion: print w/replies, xml ) Need Help??

nikolay has asked for the wisdom of the Perl Monks concerning the following question:

my $q='qqqweqwe asdasdasd zxczxczxc tyutyutyi '; my $a='zxczxczxc';
How do i remove with regexp all the chars of the $q variable content, starting from the beginning of it and down to $a, including $a variable content? -- Something like:
$q=~s#[.\n]*$a##;
-- if it could work with multiline. (As the content of both variables can change, the regexp uses * instead of +). Thank you.

Replies are listed 'Best First'.
Re: Multiline replace regexp.
by haukex (Archbishop) on May 21, 2018 at 13:16 UTC

    You haven't shown your expected output, but I think I understand what you're asking. I see several issues:

    1. The dot (.) loses its special meaning inside a [] character class, that is, [.] matches only a literal dot.
    2. I think what you're trying to say with [.\n] is probably that you want to match everything, since the dot . doesn't match \n by default. This is actually achieved by the /s modifier.
    3. You probably should be explicit in that you want to match starting at the beginning of the string by using the \A anchor.
    4. You may want to avoid the interpretation of any regex metacharacters in $a by using \Q...\E - see quotemeta and Mind the meta!
    5. Avoid the variable names $a and $b, as these are used by sort and may cause confusion when used elsewhere in the code.
    6. You haven't specified what would happen if the search string doesn't appear exactly once in $q.

    Short, Self-Contained, Correct Example:

    use warnings; use strict; my $str='qqqweqwe asdasdasd zxczxczxc tyutyutyi '; my $find='zxczxczxc'; $str=~s#\A.*\Q$find\E##s; print "<<$str>>\n"; __END__ << tyutyutyi >>

    Update: Note the above isn't aware of the concept of lines at all. If you want the string 'zxczxczxc' to be matched only when it appears on a line by itself, you need to specify that.

Re: Multiline replace regexp.
by LanX (Saint) on May 21, 2018 at 13:04 UTC
    I think you are looking for the /m modifier for multiline.

    From the end of perlretut#Using-character-classes

    no modifiers: Default behavior. . matches any character except "\n" . ^ matches only at the beginning of the string and $ matches only at the end or before a newline at the end.

    s modifier (/s): Treat string as a single long line. . matches any character, even "\n" . ^ matches only at the beginning of the string and $ matches only at the end or before a newline at the end.

    m modifier (/m): Treat string as a set of multiple lines. . matches any character except "\n" . ^ and $ are able to match at the start or end of any line within the string.

    both s and m modifiers (/sm ): Treat string as a single long line, but detect multiple lines. . matches any character, even "\n" . ^ and $ , however, are able to match at the start or end of any line within the string.

    Here are examples of /s and /m in action:

    $x = "There once was a girl\nWho programmed in Perl\n"; $x =~ /^Who/; # doesn't match, "Who" not at start of string $x =~ /^Who/s; # doesn't match, "Who" not at start of string $x =~ /^Who/m; # matches, "Who" at start of second line <---- $x =~ /^Who/sm; # matches, "Who" at start of second line $x =~ /girl.Who/; # doesn't match, "." doesn't match "\n" $x =~ /girl.Who/s; # matches, "." matches "\n" $x =~ /girl.Who/m; # doesn't match, "." doesn't match "\n" $x =~ /girl.Who/sm; # matches, "." matches "\n"

    Most of the time, the default behavior is what is wanted, but /s and /m are occasionally very useful. If /m is being used, the start of the string can still be matched with \A and the end of the string can still be matched with the anchors \Z (matches both the end and the newline before, like $ ), and \z (matches only the end):

    $x =~ /^Who/m; # matches, "Who" at start of second line $x =~ /\AWho/m; # doesn't match, "Who" is not at start of string $x =~ /girl$/m; # matches, "girl" at end of first line $x =~ /girl\Z/m; # doesn't match, "girl" is not at end of string $x =~ /Perl\Z/m; # matches, "Perl" is at newline before end $x =~ /Perl\z/m; # doesn't match, "Perl" is not at end of string

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Wikisyntax for the Monastery

    update

    added more perldoc to round up explanation.

Re: Multiline replace regexp.
by hippo (Bishop) on May 21, 2018 at 13:05 UTC
    $q =~ s/^.*$a//sm;

    The "m" is for multiline, which is a handy mnemonic.

    Update: Although, as discussed in this thread the "m" is not actually required if we understand what nikolay wants correctly. We can golf the whole thing down to:

    $q =~ s/.*$a//s;

    as here:

    #!/usr/bin/env perl use strict; use warnings; use Test::More tests => 1; my $q = 'qqqweqwe asdasdasd zxczxczxc tyutyutyi '; my $a = 'zxczxczxc'; my $want = "\ntyutyutyi\n"; $q =~ s/.*$a//s; is ($q, $want, "With /s only and no anchor - matched");
      Are the effects of /s really wanted here?

      update

      I'm confused, depending on how I understand the OP it's either /s or /m , but not both.

      Cheers Rolf
      (addicted to the Perl Programming Language and ☆☆☆☆ :)
      Wikisyntax for the Monastery

        Are the effects of /s really wanted here?

        Yes, because without /s the newlines are not matched.

        Code added for clarity:
        #!/usr/bin/env perl use strict; use warnings; use Test::More tests => 2; my $q = 'qqqweqwe asdasdasd zxczxczxc tyutyutyi '; my $a = 'zxczxczxc'; my $want = "\ntyutyutyi\n"; my $t = $q; $t =~ s/^.*$a//sm; is ($t, $want, "With /s - matched"); $t = $q; $t =~ s/^.*$a//m; isnt ($t, $want, "No /s - not matched");

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1214971]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (7)
As of 2024-04-18 09:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found