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;
}