6

I was looking to build a regex statement to always remove the first 3 lines of the string, and last 3 lines of the string (the middle part could be any n number of lines content). Any clean regex way to acheive this output? (i.e. always strip our first 3 lines and last 3 lines of the string - and preserve the middle part, which could be a variable # of lines)

Thanks.

e.g.

Input String:

"
1
2
3
<1...n # of lines content>
4
5
6
"

To desired output string:

"<1..n # of lines content>"
sidyll
  • 57,726
  • 14
  • 108
  • 151
simbatish
  • 123
  • 1
  • 1
  • 5

3 Answers3

9

The previously given solutions are really complex! All one needs is

s/^(?:.*\n){1,3}//;
s/(?:.*\n){1,3}\z//;

If you want to accept a lack of trailing newline at the end, you can use

s/\n?\z/\n/;
s/^(?:.*\n){1,3}//;
s/(?:.*\n){1,3}\z//;

or

s/^(?:.*\n){1,3}//;
s/(?:.*\n){0,2}.*\n?\z//;
ikegami
  • 367,544
  • 15
  • 269
  • 518
4

This should do the trick. You may need to replace "\n" with "\r\n" depending on the newline format of your input string. This will work regardless if the last line is terminated with newline or not.

$input = '1
2
3
a
b
c
d
e
4
5
6';

$input =~ /^(?:.*\n){3} ((?:.*\n)*) (?:.*\n){2}(?:.+\n?|\n)$/x;

$output = $1;

print $output

Output:

a
b
c
d
e
-1
for($teststring)
{
    s/<.*?>//g;
    $teststring =~ s%^(.*[\n\r]+){3}([.\n\r]).([\n\r]+){3}$%$2%;
    print "Outputstring" . "\n" . $teststring . "\n";
}

You need to test if it's under 6 lines, etc.

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Ed Heal
  • 59,252
  • 17
  • 87
  • 127
  • An issue with this approach is that if you have two or more lines in a row that would be empty if it were not for their 'newline' characters, you run into trouble. `[\n\r]+` could match any amount of newlines. Better to convert line endings to the native OS first, rather than trying to allow for any combination of \r and \n. – DavidO Aug 13 '11 at 00:14
  • 1
    Just use the \R generalized newline, then you don't have to play games with \r and \n, which creates your bug. – brian d foy Aug 13 '11 at 00:37