Try:
\x20(?![^"]*("[^"]*"[^"]*)*$)
To understand the way it works you need to go back to some basics.
How do you determine if you are within double quotes or not? Given that many regex variants don't allow variable length lookbehind expressions, the easy way is to check to see if there is an even or odd number of double quotes between where you are and what you consider to be a suitable "end" point - in this case we will assume the end of the entire string but there could be performance issues if we use that for every long blocks of text.
Therefore the first step is to move forward looking for the first double-quote after the target character and stop just before it: '[^"]*'
If we don't locate even 1 double-quote then we can't be inside a double-quoted string. If we do locate the next double-quote, then we need to keep searching to make sure that it is an "end" double-quote and not the start of one. The way to do this is to locate as many matching double-quotes as we can.
Therefore we match the double-quote we have just found, skip forward to the next one and match that:
"[^"]*"
Of course, this could be followed by more characters that are no double-quotes and so we get
"[^"]*"[^"]*
As this will match pairs of double-quotes and the trailing characters after the 2nd of the pair, we need to let this repeat as many times as possible
("[^"]*"[^"]*)*
At the end of this process we should be at the end of the string: the other alternative is that we are at a double-quote that is NOT part of a balanced pair and therefore would mean that the initial double-quote we found is actually the start of a pair and not the end (as we need). Therefore a check for being at the end of the text is all we need at this point. Put this all together and we get:
[^"]*("[^"]*"[^"]*)*$
As we don't want to actually capture all of those characters, we need to use a lookahead. Remember that what that pattern will do is to successfully match pairs of double-quotes (in even number of double-quotes): what we want to do is the exact opposite - find an odd number of double-quotes. Therefore we can use a negative lookahead to "flip" the result of the lookahead's match. When we add the check for the target character (the space in this case - and I've used the '\x20' form to make it easy to see that a space is being used) we get:
\x20(?![^"]*("[^"]*"[^"]*)*$)
Now, if you look at your pattern, and analyse what it is doing, you will see why it is possibly not working as you would expect. If we look at the inner-group:
([^"]*"[^"]*")*$
you will see that it will skip non-double-quote characters, match the double-quote, skip more characters and end up matching the 2nd double-quote. At this point it will have 2 options: the first is to repeat the sub-pattern and find the end of the next pair of double-quotes and the second is to be at the end of the string. The implication of this is that the string MUST end with the double-quoted characters
My suggestion does not have this requirement as the order of the components in the repeating group is moved around a little to allow non-quoted characters to follow the ending double-quote. There may be none, but this is not a requirement. However, by moving the double-quote character to the start of the repeating group, I had to prefix that with something that would get me to the first double-quote but would NOT be part of the repeating group.
I hope all of this makes sense! I've tried it on some dummy text that I made up (actually the text from another question in this forum that used quoted strings as well) in a regex test platform that uses the PHP functions and it seems to work as you requite. However it would have been useful to have some text sample to work with.
Susan