A solução proposta ao final do exercício perde qualidade na busca. Pensando nessa perda, fiz dessa forma:
document.querySelector("#filtra-paciente")
    .addEventListener("input", function(event) {
        var pacientes = document.querySelectorAll(".paciente");
        var textoFiltro = this.value;
        var teste = "string de teste";
        console.log(teste.substring(1,190));
        pacientes.forEach(function(paciente) {
            var nome = paciente.querySelector(".info-nome");
    //        var expressao = new RegExp(textoFiltro, "i");
            if (textoFiltro.length != 0 ){
    //            if(!expressao.test(nome.textContent)) {
                for(var i = 0; i < nome.textContent.length; i++)        // >>>>> Adicionei esse for para procurar substring iniciando em cada letra do nome.textContent
                    if(nome.textContent.substring(i, i + textoFiltro.length).toLowerCase() != textoFiltro.toLowerCase()) {
                        paciente.classList.add("invisivel");
                    } else {
                        paciente.classList.remove("invisivel");
                        break;
                    }
                    console.log("Imprimindo o classList: " + paciente.classList);
            } else {
                paciente.classList.remove("invisivel");
            }
        });
    });
Esse for extra que adicionei teria chance de ter algum impacto de performance em listas grandes? Ou teria algum bug essa forma de encarar o problema? (Não vi nenhum nos testes aqui). O resultado final, do ponto de vista do usuário do filtro, foi o mesmo que o do RegEx. Na verdade acho a solução com RegEx muito mais elegante mesmo :)
 
            