As anubhava mentions in the comment, with negative lookbehind you could do /(?<!,\s)(so)/
, which would match so
that is not preceded by a comma and a space (and capturing so
). This is a reverse from /(?<=,\s)(so)/
, which matches so
that is preceded by a comma and a space.
Your regexp /(,\s)(so)/
matches a comma, a space and so
(and captures the comma and the space in one group, and so
in another). The negation of that can be constructed using a negative lookahead, supported in all browsers, like so: /((?!,\s)..|^.?)(so)/
— it will match two characters (or less, if at the start of the string) that are not a comma and a space, then so
(and capture both the non-comma-space preceding characters, and so
).
Typically, this second approach has a drawback: when you match more than you want, the restriction against overlapping matches might make you lose a match here and there. However, in this particular case, it is not a problem, since any overlapping characters would be so
, not a comma and a space.
(EDIT: I wrote "space" here but all the expressions are written following OP's use of \s
, which is actually for whitespace, which includes more than just space.)