If you need speed then using PCRE (or some other possibly faster regex library) from C would allow the use of both a regular expression and a check whether there is a newline. Downsides: new code to maintain and debug, time to re-implementing portions of grep or perl depending on the complexity of the expression or if features such as --only-matching are used.
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pcre.h>
#define MAX_OFFSET 3
int main(int argc, char *argv[])
{
    // getline
    char *line = NULL;
    size_t linebuflen = 0;
    ssize_t numchars;
    // PCRE
    const char *error;
    int erroffset, rc;
    int offsets[MAX_OFFSET];
    pcre *re;
    if (argc < 2) errx(1, "need regex");
    argv++;
    if ((re = pcre_compile(*argv, 0, &error, &erroffset, NULL)) == NULL)
        err(1, "pcre_compile failed at offset %d: %s", erroffset, error);
    while ((numchars = getline(&line, &linebuflen, stdin)) > 0) {
        if (line[numchars-1] != '\n') break;
        rc = pcre_exec(re, NULL, line, numchars, 0, 0, offsets, MAX_OFFSET);
        if (rc > 0) fwrite(line, numchars, 1, stdout);
    }
    exit(EXIT_SUCCESS);
}
This is about 49% faster than perl -ne 'print if /.../ && /\n\z/'.
     
    
\nso maybe it would be enough to ignore last line?grep string FILEdohead -n -1 FILE | grep 'string'\n. What shell do you use?