Bob Smithsfield
Bob Smithsfield

Reputation: 35

Substring replacement using regex

I am having a terrible time with learning Perl regular expressions. I am trying to :

I know its s/# but that's all I know and all I can find. Any suggestions.

Upvotes: 1

Views: 147

Answers (2)

choroba
choroba

Reputation: 241758

The beginning of a line is matched by ^. Therefore, a line starting with a # is matched by

/^#/

If you want the # to be single, i.e. not followed by another #, you must add a negative character class:

/^#[^#]/

We do not want to replace the character following the #, so we will replace it with a non matching group (called negative look-ahead):

/^#(?!#)/

To add the replacement, just change it to

s/^#(?!#)/#####/

The full line can be matched by the following regular expression:

/^#+$/

Plus means "once or more", ^ and $ have already been explained. We just have to ignore the leading and trailing spaces (* means "zero or more"):

/^ *#+ *$/

We do not want the spaces to be replaced, so we have to keep them. Parentheses create "capture groups" that are numbered from 1:

s/^( *)#+( *)$/$1# ---------- #$2/

Upvotes: 4

Christopher Neylan
Christopher Neylan

Reputation: 8272

For your first replacement:

$line =~ s/^#/#####/;

The idea here is that you want any line that starts with a '#'. The '^' in the regex says that what follows must be at the beginning of the string.

And for your second replacement:

$line =~ s/^#+$/# ---------- #/;

This uses '^' again and '$'. The '$' at the end says that what comes before must go to the end of the string. '#+' says that there must be one or more '#' characters. So, in other words, the entire string must consist of '#'.

Here's a test script and run:

$ cat foo.pl
#! /usr/bin/perl

use strict;
use warnings;

my @lines = (
        "foo line",
        "# single comment",
        "another line",
        "#############",
        "# line",
        "############",
);

foreach my $line( @lines ){
        print "ORIGINAL:  $line\n";
        $line =~ s/^#/#####/;
        $line =~ s/^#+$/# ---------- #/;
        print "NEW:       $line\n";
        print "\n";
}

$ ./foo.pl
ORIGINAL:  foo line
NEW:       foo line

ORIGINAL:  # single comment
NEW:       ##### single comment

ORIGINAL:  another line
NEW:       another line

ORIGINAL:  #############
NEW:       # ---------- #

ORIGINAL:  # line
NEW:       ##### line

ORIGINAL:  ############
NEW:       # ---------- #

Upvotes: 2

Related Questions