Ian
Ian

Reputation: 13842

Get repeated regex matches

I have a string, example

my $str = "Dave birthday on 11/12/68 Fred enjoys cooking Wilma likes cake"

I have some strings I want to match their name AND the text up until the next match, so I am currently trying

my $re = "(Dave|Sally|Fred|John|Wilma)" # created dynamically

I can do repeated matches like

my @matches;
push @matches, [$1, $2] while $str =~ /$re/g;
warn Dumper @matches;

Not sure what I would put in to pull out $2

This will grab matches, but I am trying to find a way to match also the part inbetween up to the next match, so ideally I would end up with something like (don't care if its an array, hash or whatever).

[["Dave"," birthday on 11/12/68"],
 ["Fred"," enjoys cooking"],
 ["Wilma"," likes cake"]]

I can probably do this by splitting strings on matching positions and remainder, but I was wondering if there was any obvious regex way I was missing ?

Upvotes: 2

Views: 69

Answers (2)

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89557

Using split with a capture group to produce a hash:

#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper qw(Dumper);

my $str = 'Dave birthday on 11/12/68 Fred enjoys cooking Wilma likes cake';
my $names_re = qr/(Dave|Sally|Fred|John|Wilma)/;

my @parts = split /\s*\b$names_re\b\s*/, $str;
shift @parts;
my %result = @parts;

print Dumper \%result;

Upvotes: 1

choroba
choroba

Reputation: 241868

Use a look-ahead assertion so that the next search starts before the name that ended the previous search.

#! /usr/bin/perl
use warnings;
use strict;
use feature 'say';

my $str = 'Dave birthday on 11/12/68 Fred enjoys cooking Wilma likes cake';
my $names_re  = qr/Dave|Sally|Fred|John|Wilma/;
my $re = qr/($names_re) (.*?)(?= $names_re|$)/;

my @matches;
push @matches, [ $1, $2 ] while $str =~ /$re/g;

use Data::Dumper; print Dumper \@matches;

Upvotes: 3

Related Questions