Remove single line and multiline comments from string

Shell + coreutils + gcc compiler collection, 31 bytes

This answer may seem a bit loopholey, but I didn't see anything specifically banning it in the question.

Rather than using clumsy regular expressions, why not use the tool that was built for the job. It should have no problem giving correct results:

cpp -fpreprocessed -o- -|sed 1d

Takes input from STDIN and output to STDOUT. Normally ccp will do all preprocessing (header files, macro expansion, comment removal, etc), but with the -fpreprocessed option, it will skip most of the steps, but it will still remove comments. In addition, cpp adds a line like # 1 "<stdin>" to the beginning of the output, so the sed is there to delete it.


Retina, 35 + 1 + 2 = 38 bytes

This program consists of two files, hence I've included a 1-byte penalty for the second file.

//.*|/\*[\s\S]*?\*/|("(\\.|[^"])*")
$1

This is a simple regex replacement, using the .NET flavour (although this would work the same in most other flavours).

The idea is to match both comments and strings, but only write the match back if it was a string. By matching the strings explicitly, they are skipped when searching for comments.


Java 365

String a(String s){String o="";int m=1;for(int i=0;i<s.length();i++){String u=s.substring(i,Math.min(i+2,s.length()));char c=s.charAt(i);switch(m){case 1:m=u.equals("/*")?5:u.equals("//")?4:c=='"'?3:1;break;case 3:m=c=='"'?1:c=='\\'?2:3;break;case 2:m=3;break;case 4:m=c=='\n'?1:4;continue;case 5:m=u.equals("*/")?1:5;i+=m==1?1:0;continue;}o+=m<4?c:"";}return o;}}

Ungolfed

public static final int DEFAULT = 1;
public static final int ESCAPE = 2;
public static final int STRING = 3;
public static final int ONE_LINE_COMMENT = 4;
public static final int MULTI_LINE_COMMENT = 5;

String clear(String s) {
    String out = "";
    int mod = DEFAULT;
    for (int i = 0; i < s.length(); i++) {
        String substring = s.substring(i, Math.min(i + 2 , s.length()));
        char c = s.charAt(i);
        switch (mod) {
            case DEFAULT: // default
                mod = substring.equals("/*") ? MULTI_LINE_COMMENT : substring.equals("//") ? ONE_LINE_COMMENT : c == '"' ? STRING : DEFAULT;
                break;
            case STRING: // string
                mod = c == '"' ? DEFAULT : c == '\\' ? ESCAPE : STRING;
                break;
            case ESCAPE: // string
                mod = STRING;
                break;
            case ONE_LINE_COMMENT: // one line comment
                mod = c == '\n' ? DEFAULT : ONE_LINE_COMMENT;
                continue;
            case MULTI_LINE_COMMENT: // multi line comment
                mod = substring.equals("*/") ? DEFAULT : MULTI_LINE_COMMENT;
                i += mod == DEFAULT ? 1 : 0;
                continue;
        }
        out += mod < 4 ? c : "";
    }

    return out;
}