It is possible. You can use to *parse* [1] to convert a string into an
*Expr* [2] object. After that you can recursively walk over the parsed
expression and check whether each symbol is defined using *isdefined* [3].
Something like the following might cover what you need:
vars(vs, _) = vs
Operationally, variables are Symbols in the parse tree, minus those
occurring in e.g. the first argument of a :call expression or a
:conditional expression, or some other special forms.
You can get a feel for the structure of a parsed expression using head and
args recursively:
julia