Try the following:
_[^\]]|[^[]_
It consists of alternation _[^\]](underscore, not ]) and [^[]_(not [and underscore).
Or if you want to use look-around statements to really only match underscores, not surrounding characters:
_(?=[^\]])|_(?<=[^[]_)
, ] ((?=[^\]]), ) , [ ((?<=[^[]_), ). :
_(?:(?=[^\]])|(?<=[^[]_))