Re: How to make sure no elements from @array are inside $scalar
by McA (Priest) on Nov 14, 2014 at 10:15 UTC
|
Hi,
IMHO it's ok. I have three annotations:
If the array referred by $sites is used more than once, you could think about concatenating '_9' before doing the match.
You want to delete the item as soon as one pattern matches. Therefore you can shortcut the grep with using List::Util::any.
You could try to match against a regex which is build from the elements of the list.
my $regex = '_9(?:' . join('|', map { quotemeta } @$sites) . ')';
$text =~ /$regex/;
Regards
McA
| [reply] [d/l] [select] |
Re: How to make sure no elements from @array are inside $scalar
by pme (Monsignor) on Nov 14, 2014 at 11:21 UTC
|
use strict;
my $text = 'f000124_90181234_dp';
my $sites = [ '018', '324' ];
if (grep {$text =~ /_9$_/} @$sites) {
print "To be removed..\n";
}
| [reply] [d/l] |
Re: How to make sure no elements from @array are inside $scalar
by Loops (Curate) on Nov 14, 2014 at 14:14 UTC
|
my $text = 'f000124_90181234_dp';
my $sites = [ '018', '324' ];
print "$text To be removed"
unless $text=~/_9(...)/,{map{$_,1}@$sites}->{$1};
But using List::Util is better.
use List::Util qw(none);
print "$text To be removed"
if $text=~/_9(...)/,none {$1 eq $_} @$sites;
| [reply] [d/l] [select] |
|
| [reply] [d/l] [select] |
|
Yes, you can use "and" to much the same effect in this case. In fact it would stop a warning if the match failed and $1 was left undefined. And that's because the comma operator does not short circuit as "and" does; both expressions will be evaluated whether the first is true or false. But it can be useful.
| [reply] |
Re: How to make sure no elements from @array are inside $scalar
by Anonymous Monk on Nov 14, 2014 at 11:30 UTC
|
use strict;
use warnings;
use List::Util qw( any );
my $text = 'f000124_90181234_dp';
my $sites = [ '018', '324' ];
sub delete_me {
my ( $str, $aref, $anchor ) = @_;
return any {
index( $str, $anchor . $_ ) != -1
} @$aref;
}
if ( delete_me( $text, $sites, '_9' ) ) {
print "To be removed...\n";
}
| [reply] [d/l] |
|
(oops, it seems you want to delete if nothing matches. Just replace 'any' with 'none' then)
| [reply] |
Re: How to make sure no elements from @array are inside $scalar
by AnomalousMonk (Archbishop) on Nov 14, 2014 at 15:14 UTC
|
Note that while functions like any(), none() and a few others are currently a part of the List::Util core module, they were originally found in List::MoreUtils and only relatively recently merged into the former module. For instance, in my Strawberry Perl 5.14, those functions are still only found in the latter module. (I haven't taken the trouble to find when the merger happened.)
| [reply] [d/l] [select] |
|
As it wasn't any trouble at all, I've done it for you. ;)
The Change Log gives the import date as "Sun Oct 13 01:35 UTC 2013" which was version 1.33.
| [reply] |
Re: How to make sure no elements from @array are inside $scalar
by GotToBTru (Prior) on Nov 14, 2014 at 13:56 UTC
|
For matching at a specific position, no need to use regex, just substr.
| [reply] |
Re: How to make sure no elements from @array are inside $scalar
by Steffen (Novice) on Nov 14, 2014 at 15:28 UTC
|
Wow, thanks to all for your responses! Again learned a lot by reading through your answers. I think in the end it's a matter of taste, I personally like the List::Utils way best. Also new to me was the comma operator - really handy!
if ($text =~ /_9(...)/, none {$1 eq $_} @$sites) { print "To be remove
+d..\n" }
| [reply] [d/l] |
|
Notice that your chosen solution will only use the first match in $text that starts with '_9', so it won't work with something like 'f000124_9019_90181234_dp'.
use List::Util qw( none );
my $text = 'f000124_9019_90181234_dp';
my $sites = [ '018', '324' ];
if ($text =~ /_9(...)/, none {$1 eq $_} @$sites) {
print "$1 doesn't match anything: to be removed..\n"
}
Output:
019 doesn't match anything: to be removed..
This isn't how your original code worked. | [reply] [d/l] [select] |
|
<userid>_<8-digit-number-starting-with-9>_dp
| [reply] [d/l] |