Reputation: 397
I have following code
my $string = 'ban-3.1.2278-1.x86_64.1.rpm';
my ($substr) = ($string =~ /(.+)-\d(.+)/);
print "Result: $substr\n";
I was expecting it to return ban but its returning ban-3.1.2278, I am not able to figure it out why. Can anyone please explain me why its behaving it this way and whats the correct way to do it ?
thank you.
Upvotes: 0
Views: 77
Reputation: 5927
Split also gives what you expect. try this
my $string = 'ban-3.1.2278-1.x86_64.1.rpm';
my @substr = split('-',$string);
print "Result: $substr[0]\n";
Output
Result: ban
This script is split by the -
the which is store into the array. Then print the ban by using index key value like $substr[0]
Upvotes: 1
Reputation: 1
In the above code "my ($substr) = ($string =~ /(.+?)-\d(.+)/);", unnecessary grouping are used. Use the following code instead of that,
my $string = 'ban-3.1.2278-1.x86_64.1.rpm';
$string =~ /([a-z]+)-/i;
print "Result: $1";
If you need an answer only "ban" means use this code.
[a-z]+ - it matches more than one continuous alphabet characters(accurate matches).
i - it used for case sensitive.
$1 - it returns the value of first grouping.
OUTPUT
Result: ban
Upvotes: 0
Reputation: 174696
You need to make .+
inside the first capturing group as non-greedy by adding a quantifier ?
after +
so that it would do a reluctant match(ie, shortest possible match) or otherwise it would do a longest match.
(.+?)-\d(.+)
Code:
my $string = 'ban-3.1.2278-1.x86_64.1.rpm';
my ($substr) = ($string =~ /(.+?)-\d(.+)/);
print "Result: $substr\n";
Output:
Result: ban
Upvotes: 1
Reputation: 35198
Because the any character .
will match dashes.
If you want to limit he matching, use a characters class or non-greedy matching .*?
:
my $string = 'ban-3.1.2278-1.x86_64.1.rpm';
my ($substr) = $string =~ /([^-]*)-\d(.+)/;
print "Result: $substr\n";
Outputs:
Result: ban
Upvotes: 2