Let's say I want to extract all of the days of the week out of a
scalar such as :
$_ =
'We went to the beach on Monday but it turned out that Sunday would
have been better. The weather report Saturday said no rain until
Thursday but I asked Tuesday (a trick!) and she said it rained
Wednesday.'
I want a regex/map/grep/etc (no iterative clauses PLEASE!) that
yields:
@days = qw( Monday Sunday Saturday Thursday Tuesday Wednesday )
My best shot is:
my @days = keys %{ /((mon|tues|wednes|thurs|fri|satur|sun)day)/gi };
Which, oddly, doesn't seem to work. I say "oddly", because
/((mon|tues|wednes|thurs|fri|satur|sun)day)/gi
=
0 'Saturday'
1 'Satur'
2 'Thursday'
3 'Thurs'
4 'Tuesday'
5 'Tues'
6 'Wednesday'
7 'Wednes'
yet %{ /((mon|tues|wednes|thurs|fri|satur|sun)day)/gi }
is an empty array!? *TILT*
I'm also not crazy about the hash solution because order may be
significant.
you need non-capturing parens around the "roots" of your weekday and
weekend names.
use strict; use warnings;
use Data::Dumper;
$_ =
'We went to the beach on Monday but it turned out that Sunday would
have been better. The weather report Saturday said no rain until
Thursday but I asked Tuesday (a trick!) and she said it rained
Wednesday.' ;
my @days = /((?:mon|tues|wednes|thurs|fri|satur|sun)day)/gi;
print Dumper( \@days ), "\n";
$ ./extract_from_str.pl
$VAR1 = [
'Monday',
'Sunday',
'Saturday',
'Thursday',
'Tuesday',
'Wednesday'
];
[ALERT: double posting w/different title]
> My best shot is:
> my @days = keys %{ /((mon|tues|wednes|thurs|fri|satur|sun)day)/gi };
> Which, oddly, doesn't seem to work. I say "oddly", because
> /((mon|tues|wednes|thurs|fri|satur|sun)day)/gi
> =
>
> 0 'Saturday'
> 1 'Satur'
> 2 'Thursday'
> 3 'Thurs'
> 4 'Tuesday'
> 5 'Tues'
> 6 'Wednesday'
> 7 'Wednes'
The riddles solution involves the (?: ... ) non-capturing
(grouping only) parentheses (See the other answer to your
first posting).
Regards
M.
I think you want something like this:
Code:
my @days = qw( Sunday Monday Tuesday Wednesday Thursday Friday
aturday );
my @wanted_days = qw( Monday Sunday Saturday Thursday Tuesday
Wednesday );
my %days = map { $_ => m/(.*)day$/; } @days;
print map { "$_ => $days{$_}\n" } @wanted_days;
Output:
Monday => Mon
Sunday => Sun
Saturday => Satur
Thursday => Thurs
Tuesday => Tues
Wednesday => Wednes
or, if you want a three letter abbreviation,
Code:
my @days = qw( Sunday Monday Tuesday Wednesday Thursday Friday
aturday );
my @wanted_days = qw( Monday Sunday Saturday Thursday Tuesday
Wednesday );
my %days = map { $_ => m/^(.{3})/; } @days;
print map { "$_ => $days{$_}\n" } @wanted_days;
Output:
Monday => Mon
Sunday => Sun
Saturday => Sat
Thursday => Thu
Tuesday => Tue
Wednesday => Wed
Is this what you were after?
--
G.Etly
GE> advice please wireless 802.11 on RH8 wrote:
>> $_ =
>> 'We went to the beach on Monday but it turned out that Sunday would
>> have been better. The weather report Saturday said no rain until
>> Thursday but I asked Tuesday (a trick!) and she said it rained
>> Wednesday.'
>> @days = qw( Monday Sunday Saturday Thursday Tuesday Wednesday )
>>
>> My best shot is:
>> my @days = keys %{ /((mon|tues|wednes|thurs|fri|satur|sun)day)/gi };
>>
>> Which, oddly, doesn't seem to work. I say "oddly", because
>>
>> /((mon|tues|wednes|thurs|fri|satur|sun)day)/gi
>>
GE> I think you want something like this:
GE> Code:
GE> my @days = qw( Sunday Monday Tuesday Wednesday Thursday Friday
GE> aturday );
GE> my @wanted_days = qw( Monday Sunday Saturday Thursday Tuesday
GE> Wednesday );
huh?? he wants to GET those days from the text, not preset them.
GE> my %days = map { $_ => m/(.*)day$/; } @days;
GE> print map { "$_ => $days{$_}\n" } @wanted_days;
and where is the input text being scanned?? that is the issue here, not
how to make a hash of day names.
GE> Is this what you were after?
no it isn't. glad to see you actually make some perl comments. try
better next time.
uri
--
Uri Guttman ------ u...@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
[please don't lead quoted text with spaces]
> > advice please wireless 802.11 on RH8 wrote:
> > > $_ =
> > > 'We went to the beach on Monday but it turned out that Sunday
> > > would have been better. The weather report Saturday said no rain
> > > until Thursday but I asked Tuesday (a trick!) and she said it
> > > rained Wednesday.'
> > >
> > > @days = qw( Monday Sunday Saturday Thursday Tuesday Wednesday )
> > >
> > > My best shot is:
> > > my @days = keys %{
> > > /((mon|tues|wednes|thurs|fri|satur|sun)day)/gi }; >>
> > > Which, oddly, doesn't seem to work. I say "oddly", because
> > >
> > > /((mon|tues|wednes|thurs|fri|satur|sun)day)/gi
> > I think you want something like this:
> >
> > Code:
> > my @days = qw( Sunday Monday Tuesday Wednesday Thursday Friday
> > aturday );
> > my @wanted_days = qw( Monday Sunday Saturday Thursday Tuesday
> > Wednesday );
> huh?? he wants to GET those days from the text, not preset them.
Ok, so I mis-read. After re-reading it seems he just wants to capture
the days of the week from the string, so the answer is simple:
Code:
$_ =
'We went to the beach on Monday but it turned out that Sunday would
have been better. The weather report Saturday said no rain until
Thursday but I asked Tuesday (a trick!) and she said it rained
Wednesday.';
my @days = m#((?:mon|tues|wednes|thurs|fri|satur|sun)day)#gi;
print join(", ", @days);
Output:
Monday, Sunday, Saturday, Thursday, Tuesday, Wednesday
And the code I gave be before can be adapted/modified to change the
format of the day of the week's name.
--
G.Etly
GE> Uri Guttman wrote:
>> Gordon Etly <g...@bentsys.com> writes:
>> > > $_ =
>> > > 'We went to the beach on Monday but it turned out that Sunday
>> > > would have been better. The weather report Saturday said no rain
>> > > until Thursday but I asked Tuesday (a trick!) and she said it
>> > > rained Wednesday.'
>> > >
>> > > @days = qw( Monday Sunday Saturday Thursday Tuesday Wednesday )
>> > >
>> > > My best shot is:
>> > > my @days = keys %{
>> > > /((mon|tues|wednes|thurs|fri|satur|sun)day)/gi }; >>
>> > > Which, oddly, doesn't seem to work. I say "oddly", because
>> > >
>> > > /((mon|tues|wednes|thurs|fri|satur|sun)day)/gi
>> > I think you want something like this:
>> >
>> > Code:
>> > my @days = qw( Sunday Monday Tuesday Wednesday Thursday Friday
>> > aturday );
>> > my @wanted_days = qw( Monday Sunday Saturday Thursday Tuesday
>> > Wednesday );
>> huh?? he wants to GET those days from the text, not preset them.
GE> Ok, so I mis-read. After re-reading it seems he just wants to capture
GE> the days of the week from the string, so the answer is simple:
you misread AGAIN.
GE> Code:
GE> $_ =
GE> 'We went to the beach on Monday but it turned out that Sunday would
GE> have been better. The weather report Saturday said no rain until
GE> Thursday but I asked Tuesday (a trick!) and she said it rained
GE> Wednesday.';
GE> my @days = m#((?:mon|tues|wednes|thurs|fri|satur|sun)day)#gi;
GE> print join(", ", @days);
the OP wanted the unique set of days which is why his post had a keys on
a dereferenced but incorrect hash ref. and he wanted it in one
expressions without external loops.
also he got correct answers from other people (including myself) a while
back. try reading followups before posting another answer (correct or
not).
[please stop leading quoted text with spaces]
> ordon Etly <g...@bentsys.com> writes:
> > Uri Guttman wrote:
> > > Gordon Etly <g...@bentsys.com> writes:
> > Ok, so I mis-read. After re-reading it seems he just wants to
> > capture
> > the days of the week from the string, so the answer is simple:
> you misread AGAIN.
No I didn't:
advice please wireless 802.11 on RH8 wrote:
> Let's say I want to extract all of the days of the week out
> of a scalar
...
> I want a regex/map/grep/etc (no iterative clauses PLEASE!)
> that yields:
>
> @days = qw( Monday Sunday Saturday Thursday Tuesday Wednesday )
He wanted the days in the string (presuming in the order they appear)
and ultimately stored into an array. My example fulfills this.
> > Code:
> > $_ =
> > 'We went to the beach on Monday but it turned out that Sunday would
> > have been better. The weather report Saturday said no rain until
> > Thursday but I asked Tuesday (a trick!) and she said it rained
> > Wednesday.';
> >
> > my @days = m#((?:mon|tues|wednes|thurs|fri|satur|sun)day)#gi;
> >
> > print join(", ", @days);
> the OP wanted the unique set of days which is why his post had a keys
> on a dereferenced but incorrect hash ref. and he wanted it in one
> expressions without external loops.
advice please wireless 802.11 on RH8 wrote:
> I'm also not crazy about the hash solution because order may
> be significant.
He never said "unique", all he said was he wanted to capture the
occurrences of days of the week in the string into an array. He never
said their couldn't be duplicates. He _did_ say that "order may be
significant", which to me is in line with capturing each occurrence of a
day of the week in the string (as they appear.)
> also he got correct answers from other people (including myself) a
Actually your answer was based on the occurrences' being unique, a
requirement the OP never gave, so your answer imposes a limit the OP
most likely doesn't want, where as mine solution merely gets each
occurrence, in the _order_ they appear.
> while back. try reading followups before posting another answer
This answer I gave in my last post was correct. It was also simple and
to the point. Maybe _you_ should read the original post more carefully.
--
G.Etly
>
>
> > also he got correct answers from other people (including myself) a
>
Quite right lots of very helpful information thanks to everyone who
contributed. I see some things I did wrong (and some I did right).. I
never knew about 2 different types of parens- capturing and non-
capturing? I'm scoping out Camel now to see what's in there but I've
pretty much read it cover to cover and don't recall those terms..
Thanks again
Quite right- I had no uniqueness requirement.. Another reason my hash
solution was wrong. Good instincts on your part.
GE> my @days = m#((?:mon|tues|wednes|thurs|fri|satur|sun)day)#gi;
I was curious how to do this for any locale, so I came up with:
my @dow_names;
foreach (0..6)
{
push @dow_names, strftime('%A', localtime($_*24*60*60));
}
print Dumper \@dow_names;
which produces, for example,
LANG=bg_BG.utf8 /tmp/t.pl
$VAR1 = [
'сряда',
'четвъртък',
'петък',
'събота',
'неделя',
'понеделник',
'вторник'
];
It should be easy to extend this to the original example. This is
strictly for fun, I know the OP didn't need locales.
Are the days of the week strictly defined to be exactly 7? If yes,
this code should always work. There's got to be some Mayan-French
calendar where it's not true, though...
Ted
apw81oR> Quite right lots of very helpful information thanks to everyone who
apw81oR> contributed. I see some things I did wrong (and some I did right).. I
apw81oR> never knew about 2 different types of parens- capturing and non-
apw81oR> capturing? I'm scoping out Camel now to see what's in there but I've
apw81oR> pretty much read it cover to cover and don't recall those terms..
the camel (which edition?) is not the final reference on perl, the docs
are. you should read perldoc perlrequick, perlretut and perlre (in that
order). from perlre:
"(?:pattern)"
"(?imsx-imsx:pattern)"
This is for clustering, not capturing; it groups subexpres‐
sions like "()", but doesn’t make backreferences as "()"
does. So
@fields = split(/\b(?:a|b|c)\b/)
is like
@fields = split(/\b(a|b|c)\b/)
but doesn't spit out extra fields. It's also cheaper not to
capture characters if you don’t need to.
the docs don't use the grouping vs grabbing terminology but many perl
hackers do use those to separate the two similar concepts. perl6
rectifies this by using totally different syntax for the two of them.