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

In the code below, the if statement is not matching on any non-whitespace characters. Where is my mistake at?

print "Enter a fragment of a web address to see if it is a match fo +r the correct web site: "; chomp (my $fragment = <STDIN>); print "\n"; if ($fragment =~ m{http:// (S+) } ) { print "That is a good match for the URL\n"; } else { print "THat is not a good a match\n"; }

TIA The Catfish

Replies are listed 'Best First'.
Re: Non White space function
by ikegami (Patriarch) on Jul 17, 2020 at 21:21 UTC

    That matches "http://", followed by a space, followed by one or more "S", followed by a space. I think you want

    m{http:// (\S+) }x

    /x causes white space in the pattern to be ignored. \S is what matches a non-whitespace.


    Note that this check if the string in $fragment contains a URL; it doesn't check if the string is a URL. For that, you'd need

    m{ ^ http:// (\S+) \z }x

    Of course, that not a proper check for URLs. You get false negatives (e.g HTTP://www.perlmonks.org) and false positives. Maybe you should use Regexp::Common::URI::http instead?

    Update: Mentioned a specific solution. Thanks, haukex.

    Update: In the description, I used /s where I meant /x. Fixed.

Re: Non White space function
by haukex (Archbishop) on Jul 17, 2020 at 21:21 UTC
    m{http:// (S+) }

    You put whitespace around the capturing group (perhaps you meant to use the /x modifier?) and you forgot the backslash on the \S.

    Perhaps you want to use Regexp::Common::URI::http or URI instead of making your own regex.

      URI doesn't validate.

Re: Non White space function
by hippo (Archbishop) on Jul 18, 2020 at 08:51 UTC

    It would be unusual to find strings which did match that regex since it's a schema part of a URL and then a bunch of uppercase letter Ss with a space in between and a space at the end. But you haven't shown your input, so who knows what you are really trying to achieve? I could guess that you meant to put a backslash before the S and maybe not have those spaces in there but instead here's an SSCCE which you can tailor to your needs should you need to refine your question.

    use strict; use warnings; use Test::More; my @good = ( 'http:// S ', 'We will all go to http:// SSSSSSSS ', ); my @bad = ( 'foo', 'http:// foo ', 'https:// SSS ', 'http:// SSS', 'http://SSS ', 'HTTP:// SSS ', 'http:// SSS ', "http://\tSSS ", "http:// SSS\t", ); my $re = qr{http:// (S+) }; plan tests => @good + @bad; for my $str (@good) { like ($str, $re, "$str matched"); } for my $str (@bad) { unlike ($str, $re, "$str not matched"); }