abc
abc

Reputation: 113

Perl Regex Get token from string

I have a string $string: aa,bbbb,ccc,ddddddddd. I am trying to use a regex to return the tokens separated by the , character.

I tried this approach:

$string = "aa,bbbb,ccc,ddddddddd";

if ($string =~ /(..)\,/) {
    print "token = $1\n";
}

I got the expected output as 'aa'.

But when I try to generalize it, it doesn't work.

$string = "aaaa,bbbb,ccc,ddddddddd";

    if ($string =~ /(.*)\,/) {
        print "token = $1\n";
    }

What should I add to get 'aaaa'?

Upvotes: 0

Views: 1160

Answers (5)

michael501
michael501

Reputation: 1482

yet another way :

use strict;
use warnings;
my $string = "aaaa,bbbb,ccc,ddddddddd";
my @x;

(@x) = $string =~ /(.*?),/g;
 print join "\n",@x;

Upvotes: 0

Patrick J. S.
Patrick J. S.

Reputation: 2935

The easiest answer would be to use split, but here are some things that might help you.

First, lets see what was wrong with your regex:

The * quantifier is greedy, that means it consumes as many as possible. To avoid that, you can use the non-greedy version *? to eat as few as possible:

$string =~ /(.*?),/ # $1 is now "aa"

Next, it might be saner to use the character class [^,] (everything but ,) instead of . this way you don't have to think about the greediness of your quantifier.

To match multiple times on the same regex, you can use the g flag. \G (Match were the last match ended) comes in handy, too. I'm also including the case where there are no commas at the end of the string.

$string =~ qr/\G([^,]*)  # Capture everything but ,
              (?:,|$)     # Match , or the end of the string (and don't capture it)
             /gx;

So what could we do with it? Well, we could use it in a while loop or store the matched groups in an array:

while ($string =~ /\G([^,]*)(?:,|$)/g){
   say "token = $1"
}


my @array = $string =~ /\G([^,]*)(?:,|$)/g);
say "token = $_" foreach @array;

To store in capture groups in variables, you'll have to be careful to always use LIST context (put parens around the left side of =, or a variable nomination that starts with @, like @array (there are more ways, but those are the most general cases)).

Upvotes: 0

alpha bravo
alpha bravo

Reputation: 7948

$string = "aaaa,bbbb,ccc,ddddddddd";

if ($string =~ /([^,]*)\,/) {
    print "token = $1\n";
}

Upvotes: 0

toolic
toolic

Reputation: 62121

split is a good tool for this job:

use warnings;
use strict;

my $string = "aaaa,bbbb,ccc,ddddddddd";
my @tokens = split /,/, $string;
print "$tokens[0]\n" if @tokens;

Upvotes: 4

nu11p01n73R
nu11p01n73R

Reputation: 26667

Use lazy .*?

$string = "aaaa,bbbb,ccc,ddddddddd";

    if ($string =~ /(.*?)\,/) {
        print "token = $1\n";
    }

will select aaaa

Upvotes: 1

Related Questions