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

Masters, How do I match a string that is NOT at the end of a line? How do I prevent a match if the string is at the end? I humbly beg your wisdom.
  • Comment on How do I match a string that is NOT at the end of a line?

Replies are listed 'Best First'.
Re: How do I match a string that is NOT at the end of a line?
by BrowserUk (Patriarch) on Jun 29, 2015 at 04:20 UTC

    Use (?!$):

    $x = 'the quick brown fox jumps over the lazy fox';; print "<$1>" while $x =~ m[(......fox)]g;; <brown fox> < lazy fox> print "<$1>" while $x =~ m[(......fox)(?!$)]g;; <brown fox>

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
    I'm with torvalds on this Agile (and TDD) debunked I told'em LLVM was the way to go. But did they listen!

      Just for posterity .... it's usually:
      A quick brown fox jumps over the lazy dog
      .... one of the shortest pangrams in the English language.

      At 33 letters it's not really close to a "perfect pangram" but I think it caught on because it was easier to remember than, say,
      Veldt jynx grimps waqf zho buck
      (which means, of course, "a grass-plains wryneck climbs upon a male yak-cattle hybrid that was donated under Islamic law.")

      For PerlMonks perhaps the best compromise between perfection and relevance might be:
      Quick fox jumps nightly above wizard
      at 31 letters.

      :-)

Re: How do I match a string that is NOT at the end of a line?
by hippo (Archbishop) on Jun 29, 2015 at 08:52 UTC

    Use the dot metacharacter. eg:

    use strict; use warnings; use Test::More tests => 2; ok ("bar foo" =~ /foo/, 'Foo matched at end'); ok ("bar foo" !~ /foo./, 'Foo not matched at end');
      Thereby looking for: foo followed by any single character. Ergo, a foo that is not at the end of the line. Q.E.D.
Re: How do I match a string that is NOT at the end of a line?
by kcott (Archbishop) on Jun 29, 2015 at 21:25 UTC

    G'day davidfilmer,

    If you know the string you're looking for, which your question suggests, then there's no need to fire up the regex engine. The function rindex will find the position of the last occurence of the string in the line.

    Take a look at this script which will tell you if the string wasn't found in the line; was found at the end of the line; or was found before, but not at, the end of the line.

    #!/usr/bin/env perl -l use strict; use warnings; my $search = 'AAA'; my $offset = length $search; while (<DATA>) { chomp; my $last_find_pos = length($_) - $offset; my $found_pos = rindex $_, $search, $last_find_pos; if ($found_pos == -1) { print "'$search' not found in '$_'"; } elsif ($found_pos == $last_find_pos) { print "'$search' found at end of '$_'"; } else { print "'$search' found before (but not at) end of '$_'"; } } __DATA__ AAAAA AAAAB AAABB AABBB ABBBB BBBBB

    Output:

    'AAA' found at end of 'AAAAA' 'AAA' found before (but not at) end of 'AAAAB' 'AAA' found before (but not at) end of 'AAABB' 'AAA' not found in 'AABBB' 'AAA' not found in 'ABBBB' 'AAA' not found in 'BBBBB'

    -- Ken

Re: How do I match a string that is NOT at the end of a line?
by sandy105 (Scribe) on Jun 29, 2015 at 08:13 UTC

    Since you have asked a question which is basically a logical problem rather than perl specific problem

    Find below a simple piece of code

    $stringtomatch = "overload"; $strlen = 8; $strlen = -8;#negative length to truncate line while(<$file>){ $line = $_; #($_ is a special perl var , look it up) $lineslice = substr $line, 0, $strlen; #now go and do a match for the rest of the line }
Re: How do I match a string that is NOT at the end of a line?
by i5513 (Pilgrim) on Jun 29, 2015 at 13:37 UTC
    I would use $Match variable (seems like firefox doesn't like anchor with $ character, so maybe you can to move to $& manually), though it has performance issues:
    perl -ne 'my $string="perlmonks"; if (/$string/) { if (!/$&$/) { print } }'
    
    If you have a match before the end and at the end you will have to define what do you want Regards,
Re: How do I match a string that is NOT at the end of a line?
by Laurent_R (Canon) on Jun 29, 2015 at 17:52 UTC
    Perhaps it is sufficient to just add the  . metacharacter at the end of your pattern:
    $ perl -e ' print "matched" if "perlmonk" =~ /monk./;' ~ $ perl -e ' print "matched" if "perlmonks" =~ /monk./;' matched
    Update: I had not seen that hippo has already suggested this solution. Sorry for duplicating it.