Ellipses & Correct Space Factor

For restricted cases, \@ifnextchar is sufficient:

\documentclass{article}
\usepackage[utf8]{inputenc}

\newcommand*{\egap}{\kern\fontdimen3\font}
\newcommand*{\wordspace}{\@\space}
\makeatletter\newcommand*{\elip}{.\egap.\egap.\@ifnextchar.\egap\wordspace}\makeatother
\usepackage{newunicodechar}
\newunicodechar{…}{\elip}

\begin{document}
macro:                  \\
I\elip  I   \quad(good) \\
I\elip. I   \quad(good)

Unicode glyph:          \\
I…      I   \quad(good) \\
I….     I   \quad(good)

But—                    \\
I\elip, I   \quad(bad)  \\
I\elip! I   \quad(bad)  \\
I\elip? I   \quad(bad)

\end{document}

A fuller version requires a generalization of \@ifnextchar. Adapting egreg’s answer to a related question leads toward such a generalization:

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\elip}{ } { \elip_main: }
\NewDocumentCommand{\addtoelipexceptions}{m}
{
    \tl_gput_right:Nn \g_elip_exceptions_tl { #1 }
}
\cs_new_protected:Npn \elip_gap
{
    \kern\fontdimen3\font
}
\cs_new_protected:Npn \elip_main:
{
    .\elip_gap.\elip_gap.
    \bool_set_true:N \l_elip_apply_bool
    \peek_catcode_ignore_spaces:NF \c_space_token { \elip_check: }
}
\cs_new_protected:Npn \elip_check:
{
    \tl_map_inline:Nn \g_elip_exceptions_tl
        {
            \token_if_eq_charcode:NNT ##1 \l_peek_token
                {\bool_set_false:N \l_elip_apply_bool \prg_map_break: }
        }
    \bool_if:NTF \l_elip_apply_bool
        { \@~ }
        { \elip_gap }
}
\tl_new:N \g_elip_exceptions_tl
\ExplSyntaxOff

\usepackage{newunicodechar}
\newunicodechar{…}{\elip}

\begin{document}
macro:                  \\
I\elip  I   \quad(good) \\
I\elip. I   \quad(good)

Unicode glyph:          \\
I…      I   \quad(good) \\
I….     I   \quad(good)

But—                    \\
I…,     I   \quad(bad)  \\
I…!     I   \quad(bad)  \\
I…?     I   \quad(bad)

\addtoelipexceptions{,.!?}
Now:                    \\
I…,     I   \quad(good) \\
I…!     I   \quad(good) \\
I…?     I   \quad(good)
\end{document}    

(Improvements to expl3 style, or an actual generalized \@ifnextchar, would be welcome.)