用正则表达式删除文件中的注释

     一个公司的上机面试题。

有一个c语言写的简单代码文件input.c,要求写一个java程序,读取input.c文件的内容然后去掉注释,包括\\和\**\,注意不能删除引号里边的注释,然后保存到output.c文件。

input.c文件如下:

#include<iostream.h>

struct a {
char a /*2392839238923 /*kasdlfj*/asld*/;
char b; //23232392839
};
/*
askdashfla'
asdfalskdfhlksafdhla
fasdjfhalsdjfhlasdf
askjdfhlkajds
* /
 */
void Function(int param /*232323* / */)
{
//*2323234234l
int i = 1;//2923939
char str[] = "/*232323";
int j = 0;
i = i / j * i;
strcpy(str, "/*lakjslkdflksd*/");
}

main()
{
 

}


用正则表达式解决如下:

 

public class CommentTest extends TestCase{
	@Test
	public  void testDeleteComent(){
		BufferedReader reader = null;
		PrintWriter writer = null;
		try {
			reader = new BufferedReader(new FileReader("c:/input.c"));
			writer = new PrintWriter("c:/output.c");
			Map<String, String> map = new HashMap<String, String>();
			Pattern pattern = null;
			String line = "";
			StringBuffer content  = new StringBuffer();
			pattern = Pattern.compile("\".*?\"");//引号
			while((line=reader.readLine())!=null){
				StringBuffer sb = new StringBuffer();
				Matcher matcher = pattern.matcher(line);
				  //找到引号,用唯一标识符替换掉引号及其内容,并且保存在map中
				  while(matcher.find()){
					  String key = UUID.randomUUID().toString().toUpperCase();
					  map.put(key, matcher.group());
					  matcher.appendReplacement(sb, key);//逐一替换
				  }
				  matcher.appendTail(sb);
				  //替换一行中的//和/**/注释
				  line = sb.toString().replaceAll("/\\*.*\\*/|//.*", "");
				if (!line.isEmpty()){
					content.append(line).append("\n");
				}
			}
			//替换跨行的/**/注释 (?s)为启用 dotall 模式,把换行符\n也一块删掉
			String result = content.toString().replaceAll("(?s)/\\*.*\\*/", "");
			  //还原引号及其内容
			  for(Map.Entry<String, String> entry:map.entrySet()){
				  result = result.replace(entry.getKey(), entry.getValue());
			  }
			  writer.println(result);//写入新的文件中
			  writer.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				if (null != reader) reader.close();
				if (null != writer) writer.close();
			} catch (IOException e) {
				
			}
		}
	}
}


输入结果out.c

#include<iostream.h>
struct a {
char a ;
char b; 
};

void Function(int param )
{
int i = 1;
char str[] = "/*232323";
int j = 0;
i = i / j * i;
strcpy(str, "/*lakjslkdflksd*/");
}
main()
{
 
}



最近在看Matcher的源码,以下的替换方法与Matcher.replaceAll方法很相似,看来多看点源码还是很有用的。

//找到引号,用唯一标识符替换掉引号及其内容,并且保存在map中
				  while(matcher.find()){
					  String key = UUID.randomUUID().toString().toUpperCase();
					  map.put(key, matcher.group());
					  matcher.appendReplacement(sb, key);//逐一替换
				  }
				  matcher.appendTail(sb);


 

其中Matcher.replaceAll方法的源码如下

public String replaceAll(String replacement) {
        reset();
        boolean result = find();
        if (result) {
            StringBuffer sb = new StringBuffer();
            do {
                appendReplacement(sb, replacement);
                result = find();
            } while (result);
            appendTail(sb);
            return sb.toString();
        }
        return text.toString();
    }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值