Is there a preferred way to check for valid characters when using DCG?

item_code_2(_) -->
    ";\n",
    { false }, !.
item_code_2(C) -->
    [C], !.

This would be my preferred style. But, the first clause is a no-op. Any clause with false before a cut or side-effects is just wasting CPU time. Guess you wanted the cut before the {false}. For the second clause, a ! at the end of the last clause is always suspicious. In this case too it is not needed.

Note that I would expect “;” inside an item code name to be rare, so the first clause rarely does something. A possible better style is

item_code_2(C) :-
    \+ ";\n",
    [C].