Home > Mobile >  perl match consecutive newlines: `echo "aaa\n\n\nbbb" | perl -pe "s/\\n\\n/z/g
perl match consecutive newlines: `echo "aaa\n\n\nbbb" | perl -pe "s/\\n\\n/z/g

Time:01-27

This works:

echo "aaa\n\n\nbbb" | perl -pe "s/\\n/z/gm"

aaazzzbbbz

This doesn't match anything:

echo "aaa\n\n\nbbb" | perl -pe "s/\\n\\n/z/gm"

aaa


bbb

How do I fix, so the regex matches two consecutive newlines?

CodePudding user response:

You are applying substitution to only one line at a time, and one line will never have two newlines. Apply the substitution to the entire file instead:

perl -0777 -pe 's/\\n\\n/z/g'

CodePudding user response:

A linefeed is matched by \n

echo "a\n\n\b" | perl -pe's/\n/z/'

This prints azzb, and without the following newline, so with the next prompt on the same line. Note that the program is fed one line at a time so there is no need for /g modifier. (And which is why \n\n doesn't match.) That /m modifier is then unrelated to this example.

I don't know in what form this is used but I'd imagine not with echo feeding the input? Then better test it with input in a file, or in a multi-line string (in which case /g may be needed).

An example

use warnings;
use strict;
use feature 'say';

# Test with multiline string  
my $ml_str = "a\n\nb\n";

$ml_str =~ s/\n/z/g;  #-->  azzbz (no newline at the end)
print $ml_str;    
say '';      # to terminate the line above

# Or to replace two consecutive newlines (everywhere)
$ml_str = "a\n\nb\n";   # restore the example string 
$ml_str =~ s/\n\n/z/g;  #-->  azb\n
print $ml_str;    


# To replace the consecutive newlines in a file read it into a string
my $file = join '', <DATA>;  # lines of data after __DATA__

$file =~ s/\n\n/z/g;
print $file;  

__DATA__
one
two


last

This prints

azzbz
azb
one
twoz
last

Another way to match a newline is with the modifier /s, with which the . pattern matches linefeeds as well. So s/./z/sg also replaces all linefeeds, but then so it does with other characters as well.

See perlrebackslash and search for newline.


The /m modifier makes ^ and $ also match beginning and end of lines inside a multi-line string. Then

$multiline_string =~ s/$/z/mg;

will replace newlines inside the string. However, this example bears some complexities since some of the newlines stay.

  • Related