Jasmine Lognnes
Jasmine Lognnes

Reputation: 7107

Optional variable match?

I would like to write a regex that can extract the 2, 3, or 4 characters in the following strings:

a b
a b c
a b c d

I wrote the following code to do this:

#!/usr/bin/perl

use strict;
use warnings;

my @a = ("a b", "a b c", "a b c d");

while (defined (my $line = shift @a)) {

    my ($c1, $c2, $c3, $c4) = "";
    ($c1, $c2, $c3) = $line =~ /^(.*?)\s(.*?)\s(.*?)?.*?/;
    print "$c1, $c2, $c3\n";
}

However, the above fails because $c3 cannot be found in the first two strings. How can I make $c3 and $c4 optional, so the regex doesn't fail when there is nothing to match for those?

Upvotes: 1

Views: 76

Answers (4)

Dave Cross
Dave Cross

Reputation: 69314

You've got some good answers using split. But you can do this easily with regexes too. You just need to attack it from a slightly different direction.

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

my @strings = ("a b", "a b c", "a b c d");

foreach (@strings) {
  my @matches = /(\S+)/g;
  say "@matches";
}

Upvotes: 1

Kenosis
Kenosis

Reputation: 6204

How can I make $c3 and $c4 optional, so the regex doesn't fail when there is nothing to match for those?

Unless you must use individuals variables, consider using an array to hold the characters you want:

use strict;
use warnings;

my @a = ( "a b", "a b c", "a b c d" );

for my $line (@a) {
    my @chars = split ' ', $line;
    #my @chars = $line =~ /\S+/g; # Or use this regex to capture the chars
    print join( ', ', @chars ), "\n";
}

Output:

a, b
a, b, c
a, b, c, d

Hope this helps!

Upvotes: 3

Borodin
Borodin

Reputation: 126742

To account for any number of fields in your string, I suggest you use an array instead of a list of scalar variables.

In any case, if you have variables like $f1, $f2, $f3, $f4 then it is a sign that you probably want an array @f instead. Then you can use $f[0], $f[1], $f[2], $f[3].

Like this

use strict;
use warnings;

my @data = ('a b', 'a b c', 'a b c d');

for (@data) {
  my @fields = split;
  print join(', ', @fields), "\n";
}

output

a, b
a, b, c
a, b, c, d

Upvotes: 1

mpapec
mpapec

Reputation: 50667

In this case split is more practical than regex,

for my $line (@a) {

    my ($c1, $c2, $c3, $c4) = split " ", $line;
    print "$c1, $c2, $c3\n";
}

Upvotes: 1

Related Questions