【CodeForWork】替换添加双引号

原创 2013年12月06日 11:27:37

业务背景:

在工作中,有生产数据库和测试数据库;当出现数据不一致时,可能需要打数据补丁,也就是导出部分表中的全部或者部分数据插入到缺失的数据库中;

而在我的工作环境中,有一个特殊的现象即该系统的数据库中的关键字是必须大小写区分且操作表名和字段必须加双引号,这是在设计系统时制定好的;

在plsql中导出的sql语句,其字段都是如下形式:

insert into "test" (id,name,pwd)values('1','lan','lanlan');
insert into "test" (id,name,pwd)values('2','li','lili');

插入到数据库中应该是如下形式:

insert into "test" ("id","name","pwd")values('1','lan','lanlan');
insert into "test" ("id","name","pwd")values('2','li','lili');


虽然可以借助一些editor来查找替换,但是当导的表特别多的时候,非常不便

于是,就写了一个java程序来解决这个问题,写的很垃圾,轻喷!

原始思路:

手动操作的过程是:

1选取id,name,pwd 

2将,号替换成”,“变为:(id","name","pwd)

3 头尾再手动加一个引号;(“id","name","pwd”)

4将(“id","name","pwd”)设为替换为,将原不带引号的设为目标,进行全文替换

我是从这个手动思路来设计程序的思路;

1以;分号获取完整一个sql语句

2以values为分割split出两个部分,肯定是取第一部分也就是split("values")[0]

3将这部分中的逗号替换为”,“加上引号

4获取小括号中间的部分

5将(替换为(“  将)替换为")

6将处理完成的标准目标字符串作为替换字符串,replaceAll整个文档即可


详细源码:

下面是完善了一部分的,很遗憾没有保留好最开始的代码;

package com.lan.main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 替换类
 * @author lanchenghao
 */
public class Replace {

	/**
	 * 开始处理替换
	 * @param sourceFilePath 	源文件路径
	 * @param saveFilePath	  	保存文件路径
	 * @throws Exception
	 */
	public static void beginExec(String sourceFilePath,String saveFilePath) throws Exception{
		// TODO 字符串来源--文件读取
		File file = new File(sourceFilePath);
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(file);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		InputStreamReader isr = new InputStreamReader(fis,"GBK");
		BufferedReader bufferedReader = new BufferedReader(isr);
		String source = "";
		while(bufferedReader.ready()){
			source  = source + bufferedReader.readLine()+"\r\n";
		}
		
		//TODO 关闭处理
		bufferedReader.close();
		isr.close();
		fis.close();
		
		System.out.println("读取文件:"+source);
		//获取替换内容
		String replaceContent = obtainReplaceContent(source);
		System.out.println(replaceContent);
		//获取替换目标
		String replaceTarget = obtainReplaceTarget(source);
		System.out.println(replaceTarget);
		
		//开始替换
		String result  = obtainResult(source,replaceTarget,replaceContent);
		
		//输出替换
		System.out.println(result);
		File file2 = new File(saveFilePath);
		FileOutputStream fos = new FileOutputStream(file2);
		OutputStreamWriter osw = new OutputStreamWriter(fos);
		
		//TODO 关闭处理
		osw.write(result);
		osw.flush();
		osw.close();
	}
	
	/**
	 * 获取替换目标内容
	 * @param source 源字符串
	 * @return
	 */
	public static String obtainReplaceContent(String source){
		//TODO 冗余处理
		String[] execed1 = source.split(";");
		String[] execed2 = execed1[0].split("values");//去掉一个
		String execed3 = execed2[0].replaceAll(", ","\",\"");
		
		Pattern p = Pattern.compile("\\([^(^)]*\\)");//获取小括号及内字符串
		Matcher m1= p.matcher(execed3);
		String replaceContent = "";
		if(m1.find()){
			replaceContent = m1.group();
		}
		replaceContent = replaceContent.replaceAll("\\(", "\\(\"").replaceAll("\\)", "\"\\)");
		return replaceContent;
	}
	
	/**
	 * 获取要替换的内容
	 * @param source 源字符串
	 * @return
	 */
	public static String obtainReplaceTarget(String source){
		String[] execed1 = source.split(";");
		String[] execed2 = execed1[0].split("values");//去掉一个
		Pattern p = Pattern.compile("\\([^(^)]*\\)");//获取小括号及内字符串
		Matcher m2= p.matcher(execed2[0]);
		String replaceTarget = "";
		if(m2.find()){
			replaceTarget = m2.group();
		}
		return replaceTarget;
	}
	
	/**
	 * 获取替换后的结果
	 * @param source 
	 * @param replaceTarget 替换目标
	 * @param replaceContent替换内容
	 * @return
	 */
	public static String obtainResult(String source,String replaceTarget,String replaceContent){
		String result  = source.replace(replaceTarget,replaceContent);
		return result;
	}
}

整个程序如果只是实现了功能而不提供使用的便捷性,那么同手动替换是没有区别的;又写了一个粗糙的界面:

package com.lan.main;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
 *转换程序主入口
 * @author lanchenghao
 */
public class TransUI {

	private JFrame jFrame;
	private int countExec;
	private File[] sourceFiles;
	private List<String> sourceFilePaths = new ArrayList<String>();
	private List<String> saveFilePaths = new ArrayList<String>();
	private Replace replace;
	public static void main(String[] args) {
		new TransUI().createUi();
	}
	
	/**
	 * 创建界面
	 */
	public void createUi(){
		//TODO 多线程 监听处理
		jFrame = new JFrame("自动补全引号-by小兰-献给为数据库导表抓狂的同事们");
		jFrame.setBounds(200, 100,600,300);
		jFrame.setDefaultCloseOperation(jFrame.EXIT_ON_CLOSE);
		jFrame.setResizable(false);
		jFrame.setLayout(null);
		
		final JTextArea choosePathArea = new JTextArea(3,20);
		final JTextField savePathText = new JTextField();
		
		choosePathArea.setLineWrap(true);
		savePathText.setSize(150, 24);
		
		JLabel browseLabel = new JLabel("请选择欲替换文件:");
		browseLabel.setBounds(5,5,150,24);
		JButton browseBtn = new JButton("浏览");
		browseBtn.setBounds(155, 5,120, 24);
		
		JLabel choosePathLabel = new JLabel("文件列表:");
		final JLabel showChooseCount = new JLabel();
		showChooseCount.setBounds(5, 61, 150, 24);
		choosePathLabel.setBounds(5, 30, 150, 24);
		int h = 100;
		JLabel setOutPathLabel = new JLabel("可以指定保存目录");
		setOutPathLabel.setBounds(5, 55+h, 150, 24);
		JButton outpathBtn = new JButton("指定");
		outpathBtn.setBounds(155, 55+h, 120, 24);
		JLabel help = new JLabel("默认保存到原文件目录并以原文件名+Re.sql保存");
		help.setBounds(155, 55+h,300, 24);
		JLabel savePathLabel = new JLabel("保存目录(暂未开通):");
		savePathLabel.setBounds(5, 80+h, 150, 24);
		savePathText.setBounds(155, 80+h, 200, 24);
		
		final JLabel resultLabel = new JLabel("未开始");
		resultLabel.setBounds(5, 115+h, 150, 24);
		JButton execBtn = new JButton("开始替换");
		execBtn.setBounds(155, 115+h, 120, 24);
		
		JScrollPane jScrollPane = new JScrollPane(choosePathArea,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		jScrollPane.setBounds(155, 30,350, 124);
		jFrame.add(browseLabel);
		jFrame.add(browseBtn);
		jFrame.add(showChooseCount);
		jFrame.add(choosePathLabel);
		jFrame.add(jScrollPane);
		jFrame.add(help);
		
		/*jFrame.add(setOutPathLabel);
		jFrame.add(outpathBtn);
		
		jFrame.add(savePathLabel);*/
		
		jFrame.add(resultLabel);
		jFrame.add(execBtn);
		
		jFrame.setVisible(true);
		
		browseBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser jFChooser = new JFileChooser();
				jFChooser.setFileSelectionMode(jFChooser.FILES_ONLY);
				jFChooser.setMultiSelectionEnabled(true);
				int re = jFChooser.showOpenDialog(jFrame);
				if(re == jFChooser.APPROVE_OPTION){
					sourceFiles = jFChooser.getSelectedFiles();
					for(int i=0,c=sourceFiles.length;i<c;i++){
						sourceFilePaths.add(sourceFiles[i].getPath());
						String temp = sourceFiles[i].getPath();
						saveFilePaths.add((temp.split("\\."))[0]+"Re.sql");
						choosePathArea.append(sourceFiles[i].getPath()+"\r\n");
					}
					showChooseCount.setText("共选择"+sourceFiles.length+"个文件");
					resultLabel.setText("准备就绪");
				}
			}
		});
		outpathBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser jFChooser2 = new JFileChooser();
				jFChooser2.setFileSelectionMode(jFChooser2.FILES_ONLY);
				int re = jFChooser2.showOpenDialog(jFrame);
				if(re == jFChooser2.APPROVE_OPTION){
				}
			}
		});
		execBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					for(int i=0,c=sourceFiles.length;i<c;i++){
						replace.beginExec(sourceFilePaths.get(i), saveFilePaths.get(i));
						resultLabel.setText("第"+i+"个文件处理完毕");
						countExec = countExec + 1;
					}
					resultLabel.setText("成功处理:"+countExec+"个文件");
				} catch (Exception e1) {
					e1.printStackTrace();
					resultLabel.setText("处理失败:"+(sourceFiles.length-countExec)+"个文件未成功处理");
				}
			}
		});
	}
}

虽然代码很垃圾,程序没啥可圈点的,但是很高兴,因为终于能凭着自己的code来解决实际的问题,给自己赞一个;

后续优化的地方有很多,而且早晨起来,发现可以将其改造成一个多条件替换的,至于用不用线程,感觉没必要;

附程序运行图:





python字符串中的单双引号及转义解释

转自http://blog.csdn.net/zyz511919766/article/details/22668077 python中字符串可以(且仅可以)使用成对的单引号、双引号、三个双引号...
  • wangchao701123
  • wangchao701123
  • 2017年02月28日 21:46
  • 405

正则表达式,由于双引号引发的一些事

# 文章没有技术含量,只是对自己所犯错误的反省 由于公司的反馈网站没有记住密码与自动登录功能,导致每次去访问都要输入用户名和密码。反馈网站还作为公司内外网交互通道,所以每天访问的次数比较多,为了...
  • sela01
  • sela01
  • 2013年02月21日 22:42
  • 839

和双引号添加

你可能会好奇为什么我们使用尖括号内为iostream,和双引号添加。H。答案是角括号是用来告诉编译器,我们包括头文件,包括编译器。双引号告诉编译器,这是头文件,我们提供,这使它在当前目录中包含源代码首...
  • u014260366
  • u014260366
  • 2014年03月22日 16:08
  • 254

正则表达式给查找到的内容加引号

首先介绍一下正则表达式的基本语法,不使用任何一门语言,就使用notepad++进行正则表达式的操作。 正则表达式:正则表达式表达就是操作字符串的一个规则,正则表达式使用了特殊的符号表示。 正则表达式对...
  • u014552678
  • u014552678
  • 2017年06月19日 13:17
  • 951

python处理数据——去除字符串两端的引号

在用python处理数据,会出现获得的数据本身两端带有引号,而我们需要的是形如xxx,而不是“xxx”否则就会出现问题。比如: 『解决方法一:』 使用lstrip()和rsrtip()字符串函数函...
  • wang_shen_tao
  • wang_shen_tao
  • 2016年09月16日 16:42
  • 13766

在PHP中使用正则表达式进行查找替换

1. preg_match — 执行一个正则表达式匹配 int preg_match ( string $pattern , string $subject [, array &$matches [...
  • zhxp_870516
  • zhxp_870516
  • 2013年06月09日 10:46
  • 3761

c++中双引号的有什么作用

C++ 双冒号开头的语法是什么意思? 2015-01-15 14:30sapient_82 | 浏览 229 次  编程语言软件 namespace IceDelegateM { namesp...
  • u013176681
  • u013176681
  • 2015年11月11日 13:51
  • 1646

python中单引号,双引号,多引号区别

python字符串通常有单引号('...')、双引号("...")、三引号("""...""")或('''...''')包围,三引号包含的字符串可由多行组成,一般可表示大段的叙述性字符串。在使用时基本...
  • yas12345678
  • yas12345678
  • 2016年07月31日 14:05
  • 3498

oracle 中使用单引号(')和双引号(")

oracle 中使用单引号(')和双引号(")   在ORACLE中,单引号有两个作用:           1:字符串是由单引号引用---字符串引用。           2:转义。 转义时:单...
  • zh521zh
  • zh521zh
  • 2015年04月10日 11:43
  • 4379

js中单引号和双引号的使用区别

1.引入 在jquery或者js中拼接字符串时,使用单引号和双引号是没有区别的,都可以被成功解析成字符串,但是,在一些复杂的字符串拼接时,需要单引号和双引号的混合使用时,就需要注意了。最近在项目中写...
  • ya_1249463314
  • ya_1249463314
  • 2016年12月21日 11:30
  • 5350
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【CodeForWork】替换添加双引号
举报原因:
原因补充:

(最多只允许输入30个字)