http://www.perlmonks.org?node_id=812720

jonnyfolk has asked for the wisdom of the Perl Monks concerning the following question:

Further to my previous post on XML::Simple I am using the advice of the good monks to loop through the user_agent field.

foreach my $browser ( values %{$data->{devices}->{device}} ) { my $useragent = lc($browser->{user_agent}); my $userfb = lc($browser->{fall_back}); print Dumper(\$useragent, \$userfb, \$user); }

However adding a pattern match to the loop reduces the results to a mere couple and I really don't understand why! Can anyone enlighten me as to why this is affecting the behaviour of the loop and how I can phrase the statements so that the loop runs through all the listed user agents, while comparing the http_user_agent?

#!/usr/bin/perl -w use strict; print "Content-type: text/html\n\n"; # use module use XML::Simple; use Data::Dumper; use LWP::Simple; my $url = 'http://wurfl.sourceforge.net/web_browsers_patch.xml'; my $user = $ENV{'HTTP_USER_AGENT'}; $user = lc($user); my $content = get($url); # create object my $xml = new XML::Simple; # read XML file my $data = $xml->XMLin($content); # print output my @agents; my $check; foreach my $browser ( values %{$data->{devices}->{device}} ) { my $useragent = lc($browser->{user_agent}); my $userfb = lc($browser->{fall_back}); $user =~ /$useragent/; print Dumper(\$useragent, \$userfb, \$user); }

Replies are listed 'Best First'.
Re: unexpected loop behaviour when pattern matching
by ikegami (Patriarch) on Dec 14, 2009 at 15:58 UTC
    You're treating arbitrary text as a regex pattern, so it doesn't match what you expect it to match and it you get regex pattern compilation errors:
    Unmatched ( in regex; marked by <-- HERE in m/mozilla/5.0 ( <-- HERE m +acintosh; u; safari/525/ at script.pl line 30.

    I'm rather curious as to why you didn't mention that you were getting an error.

    Perhaps you want

    # Does $user contain the string from $useragent $user =~ /\Q$useragent\E/
    or
    # Is $user equal to the string from $useragent $user =~ /^\Q$useragent\E\z/
    or
    # Is $user equal to the string from $useragent $user eq $useragent
      Thanks for the advice - my apologies for not pointing out the error message. I wasn't able to access my error logs but should have switched on Carp so my bad!!
Re: unexpected loop behaviour when pattern matching
by jethro (Monsignor) on Dec 14, 2009 at 16:00 UTC

    It would be helpful if you posted the script output and especially error messages you get as well. Then we don't need to copy and execute your code just to see what happens

    With your script I get an error message: "Unmachted ( in regex; marked by <-- HERE in m/mozilla/5.0 ( <-- HERE macintosh;...". I assume you see the same. It means you have a regex special character in the string you are using as pattern.

    The culprit is an opening parenthesis without a closing one, leading to an error message. Solution: Use the function quotemeta() to escape any possible character that could have a special meaning in regexes

      Apologies - I hadn't seen the error message. I should be more careful
Re: unexpected loop behaviour when pattern matching
by Khen1950fx (Canon) on Dec 14, 2009 at 19:44 UTC
    I used a simplified version of your script. I think that this is what you're looking for:

    #!/usr/bin/perl use strict; use warnings; use XML::Simple qw(:strict); use Data::Dump::Streamer; use LWP::Simple; print "Content-type: text/xml\n\n"; my $user = $ENV{'HTTP_USER_AGENT'}; $user = lc $user; my $url = 'http://wurfl.sourceforge.net/web_browsers_patch.xml'; my $xml = XML::Simple->new; my $content = get($url); my $data = $xml->XMLin( $content, forcearray => ['generic'], keyattr => [ 'web_browsers']); print Dump($data);