Write a program which replaces with spaces the braces in cases where braces in places cause stasis You are a project manager. One day, one of your programmers went insane (not your fault) and took all the expressions in the codebase and added random brackets to them, before quitting on the spot, ranting about your incompetence (also not your fault). This would be an easy fix, however, for some reason you aren't using revision control (totally not your fault). And for some reason, none of the other programmers want to go through every expression to fix up the mismatched brackets (by the way, that is not your fault). Programmers these days, you think to yourself. You will have to do it yourself. The horror! Such tasks were supposed to be beneath you...

The input will be a single line, which will contain a number of left brackets (( [ {) and right brackets () ] }). It also may, but not always, contain comments (/* */) and string literals (" " or ' ') and various numbers, letters, or symbols.

There will be at least one bracket (outside of a comment or string literal) that does not have a corrosponding opposite (outside of a comment or string literal). For example, an errant } without a { prior. Another example: a ( which does not have a ) afterwards. Your program will replace with a space the minimum number of brackets required to make the brackets match up. 

Examples:

(4 + (2 + 3))] ==> (4 + (2 + 3))  (the square bracket at the end)
][][[]] ==>  [][[]] (the square bracket at the start)
("Hel(o!")) ==> ("Hel(o!")  (the parenthesis at the end)
( /* )]*/ ==>   /* )]*/  (the parenthesis at the start)
{()] ==>  ()  (the curly bracket and the square bracket)


Input can be taken from whichever way is most convenient (STDIN, command line argument, reading from a file, etc.) 
If there is more than one way to resolve the mismatch with the same number of removals, either is acceptable.  
There will be only mismatches in brackets. String literals and comments will always be correctly formed. 
The title comes from this SO thread  
There will never be any quotes in comments, quotes in quotes, comments in comments, or comments in quotes. 


This is code golf, so minimum number of bytes wins. Ask questions in comments if the specification is not clear.
Ruby, 223 characters

This one turned out a bit long.

u,b,i=[],[[],[],[]],-1
s=gets.gsub(/(\/\*|"|').*?(\*\/|"|')|~/){|m|u+=[m];?~}
s.chars{|c|i+=1
(t='{[('.index(c))?b[t].push(i):((t='}])'.index(c))&amp;&amp;(b[t].pop||s[i]=' '))}
b.flatten.map{|l|s[l]=' '}
puts s.gsub(/~/){u.shift}


What it does is take out the strings and comments first, so they don't get counted (and puts them back in later).

Then, it goes through the string character by character. When it finds an opening brace, it stores its position. When it finds a closing brace, it pops from its respective open brace storage array.

If pop returns nil (i.e. there weren't enough opening braces), it removes the closing brace. After this entire thing is done, it removes the remaining extra opening braces (i.e. there weren't enough closing braces).

At the end of the program, it puts all the strings and comments back and outputs them.

Ungolfed:

in_str = gets

# grab strings and comments before doing the replacements
i, unparsed = 0, []
in_str.gsub!(/(\/\*|"|').*?(\*\/|"|')|\d/){|match| unparsed.push match; i += 1 }

# replaces with spaces the braces in cases where braces in places cause stasis
brace_locations = [[], [], []]
in_str.each_char.with_index do |chr, idx|
    if brace_type = '{[('.index(chr)
        brace_locations[brace_type].push idx
    elsif brace_type = '}])'.index(chr)
        if brace_locations[brace_type].length == 0
            in_str[idx] = ' '
        else
            brace_locations[brace_type].pop
        end
    end
end
brace_locations.flatten.each{|brace_location| in_str[brace_location] = ' ' }

# put the strings and comments back and print
in_str.gsub!(/\d+/){|num| unparsed[num.to_i - 1] }
puts in_str