Showing entries with tag "Regexp".

Found 5 entries

Perl: Matching multiple patterns with a regex

Perl has regular expressions built in to the core of the language and they are very powerful. It's easy enough to find a single match with a regexp:

# Find the *first* three letter word in the string
my $str = "one two three four five six seven eight nine ten";
my @x   = $str =~ m/\b(\w{3})\b/; # ("one")

If you want to find all of the three letter words you can add the g modifier to the end of your regex to tell it to match "globally".

# Find *all* the three letter words
my $str = "one two three four five six seven eight nine ten";
my @x   = $str =~ m/\b(\w{3})\b/g; # ("one", "two", "six", "ten")

You can also iterate on your global regexp if you want to get the matches one at a time:

my $str = "one two three four five six seven eight nine ten";
my @x   = ();
while ($str =~ m/\b(\w{3})\b/g) {
    push(@x, $1);
}

print join(",", @x); # "one,two,six,ten"
Leave A Reply

Perl: Array of all regexp captures

Perl v5.25.7 added support for the @{^CAPTURE} variable which wrapped all the regexp parenthesis captures up into an array. If you need this functionality in an older version of Perl you can use this function:

my $str =  "Hello Jason Doolis";
$str    =~ /Hello (\w+) (\w+)/;

my @captures = get_captures(); # ("Jason", "Doolis")
sub get_captures {
    no strict 'refs';

    my $last_idx = scalar(@-) - 1;
    my @arr      = 1 .. $last_idx;
    my @ret      = map { $$_; } @arr;

    return @ret;
}
Leave A Reply

Perl: Slurp entire file in a one liner

I need to change some text in a file that's spread across multiple lines. This means perl -pE won't work because it treats each line as a separate regexp. Reading the file in to one big string and then running a multiline regexp is the best solution.

Using -0777 tells Perl to read the entire file in to one string and allows multi-line regexps to work as intended.

If you have an input file with the content like:

if (foo
    && bar && !true) {
    # Do stuff
}

You can change the if statement with a one-liner like this:

perl -0777 -pE 's/\(foo.*?\)/(test)/s' /tmp/input.txt
Leave A Reply

Perl: Named captures in regexps

In a regular expression you can capture strings into variables using the default syntax:

$str = "2020-05-20";
$str =~ m/(\d{4})-(\d{2})-(\d{2})/;

printf("Year: %s Month: %s Day: %s\n", $1, $2, $3);

In a more complex regular expression/string things may move around. In this case it's better to use named captures instead of numeric captures. This can be done by using the (?<name>) syntax. This will capture that parenthesis pair in to the hash %+ with the name specified.

$str = "2020-05-20";
$str =~ m/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;

printf("Year: %s Month: %s Day: %s\n", $+{year},$+{month},$+{day});

Using named captures you can easily update your regular expression if the position of elements in your string change.

Note: If you use named captures, Perl also populates the numeric equivalent.

Leave A Reply

Perl: doing a regexp replace on an array

I have an array of items that I want to do a quick regexp replace on each element. Here is a very elegant solution:

@names = ("John", "Paul", "george", "Ringo");
s/^g/G/g for @names;
print join(", ",@names);
Leave A Reply