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

I have what I thought was a very simple question. It's really simple, I'm sure, but how do you compare 2 string variables, to determine if the value of the second is included in the first? e.g. $file="fielname.txt" $ext=".htm" I need to determine if the value of $file does not include the value of $ext

Replies are listed 'Best First'.
RE: variable comparison
by dempa (Friar) on May 25, 2000 at 17:33 UTC
    Have a look at the "index" function:
    index STR,SUBSTR,POSITION The index function searches for one string within another, but without the wildcard-like behavior of a full regular-expression pattern match. It returns the position of the first occurrence of SUBSTR in STR at or after POSITION. If POSITION is omitted, starts searching from the beginning of the string. The return value is based at `0' (or whatever you've set the `$[' variable to--but don't do that). If the substring is not found, returns one less than the base, ordinarily `-1'.

    HTH! /dempa

RE: variable comparison
by Simplicus (Monk) on May 25, 2000 at 18:03 UTC
    If all you are trying to do is determine the extension of a file, you can use the function
    substr string, pos, [n, replacement]

    which extracts and returns a substring n characters long, starting at position pos, from a given string. If pos is negative, the substring starts at the end of the string instead, so something like:
    my $ext = ".htm"; my $filename = "filename.htm"; if ($ext eq substr ($filename, -4)) { #whatever } else { #whatever else }

    Also, substr can be put to more interesting uses. consider:
    • if n is omitted, everything to the end of the string is included.
    • if n is negative, that many chars are left off the end of the string.


    For more information, consult Perl in a Nutshell,
    ISBN 1-56592-286-7, published by O'Rielly.
    Simplicus
      i like the substr approach myself, although i would make the small change of using the length function instead of hard coding the length of $ext.
      if (substr($filename, -length($ext)) eq $ext) { # do stuff } else { # do other stuff }
        Agreed. I've been brainwashed by Redmond to assume that an
        extension is three characters long. My early DOS training
        is to blame for that. (good ol' 8.3 notation, you know?)

        Using a regex to hunt for the dot is out of the question,
        because you might have a filename "foo.bar.htm" for example.
        Of course, you could always look for the last instance of
        the . in the filename, but . . . in the interst of having
        clearer code, I like the substr approach better than the
        regex (if only this once ;-) )
Re: variable comparison
by swiftone (Curate) on May 25, 2000 at 17:54 UTC
    As mentioned you can use either index or a regex. If you are specifically looking to check a file extension, you'll want to ensure that the extension is at the end of the string. (That is, you don't want "file.htm.txt" to show up as a .htm file.)
    The Regex way: Corrected, as I too fell for the .
    $ext="\.htm"; if($file=~ /$ext$/){ #Extension is at end of file # The final $ matches the end of the string. }
    The edit way:
    if((index ($filename, $ext) + 1 + length($ext))==length($filename)){ #Extension was at end of $filename #Untested, I might be off by one }
RE: variable comparison
by muppetBoy (Pilgrim) on May 25, 2000 at 17:41 UTC
    You could try something like:
    if ($file !~ /$ext/) { ..do something if $file does not contain $ext.. }
    I think this is what you are after....
    Update: Sorry I didn't see the . in the .htm. That will break this solution as the . will resolve to 'any character'.
Re: variable comparison
by perlcgi (Hermit) on May 25, 2000 at 17:47 UTC
    $file="filename.txt"; $ext=".txt"; if ($file =~ /$ext$/){ print "match\n"} else {print "nomatch\n"}
      Nope. That finds "Xtxt" because you aren't escaping the dot. Moral: don't use regex when a literal match will do, or learn about \Q.
RE: variable comparison
by geektron (Curate) on May 25, 2000 at 23:42 UTC
    i actually use this: my ( $name, $new_ext ) = split /./, $file; if ( $new_ext eq $ext ) { do something } but i wouldn't include the . in $ext, since it's always used for extensions. . . Correction - this would also break on filenames like foo.bar.baz. . .
Re: variable comparison
by princepawn (Parson) on May 25, 2000 at 17:35 UTC
    I am not sure exactly what you are doing, but for a more structural approach to filenames and extensions, try File::Basename Terrence "I dont answer Anonymous Monks' Questions" Brannon