最近在做毕设,其中一个环节是分析qq聊天记录,在分析之前需要先把qq聊天记录导出,然后存入数据库中,qq聊天记录导出后是文本文档,导出方式:

1.登录qq后,点击任意一个好友,查看与他的聊天记录,点击聊天记录界面的小喇叭图标。

2.点击小喇叭图标后就可以选择自己要导出的聊天记录了,在要导出的人名或者群名上右键单击,选择导出聊天记录,导出格式为文本文档。

导出的文本文档格式性非常强,看下图:

我们大致分析一下这个格式,最上面那几行说明性的文字直接删去,主要看聊天记录部分,先是日期,然后一个空格,然后是时间,再一个空格,然后是用户名,换行之后就是具体的内容,正常的文档就是这样的格式,没有问题,可是有时候我们发送的qq消息中有换行符,这样的话给我们的导出记录增添了一些复杂性,所以要先对这个文档进行简单的处理。

先说说我的一个整体思路吧,每条记录的第一行,不同信息之间都有一个空格,所以我想把记录的正文内容也放在第一行,就是有时间的那一行,在记录正文和姓名之间加一个空格,这样的话每一行就是一条记录,在读取一行的信息之后,可以使用String自带的函数split(),参数是一个空格将String拆分成一个长度为4的数组。然后遍历数组插入数据库中。

基于这样的思路,我要对文档进行以下处理:

1.删除记录正文中的所有空格,避免在使用split函数时出现不必要的麻烦。对于时间日期那一行的空格则不必删除,这也就说明了这里不能用查找替换来做。

2.正文中可能会存在换行符,这个也要去除。

public class R2DB {

    public static void main(String[] args) {
//处理原始文档,处理后的文档存入999.txt中
//处理之前先把文档前面的说明性文字去掉
processTxt();
//读取原始文档并插入数据库
readAndInsert();
} private static void readAndInsert() {
String sql = "";
try {
File file = new File("F:\\test\\999.txt");
String str = null;
BufferedReader br = new BufferedReader(new FileReader(file));
QQChat qqChat = new QQChat();
List<QQChat> list = new ArrayList<QQChat>();
while ((str = br.readLine()) != null) {
String[] strs = str.split(" ");
qqChat.setQqDate(strs[0]);
qqChat.setQqTime(strs[1]);
qqChat.setQqUser(strs[2]);
/**
* 有的消息内容为空,拆分后数组的长度为3,对于这种消息,
* 设置它为未知消息
*/
if (strs.length==4) {
qqChat.setQqContent(strs[3]);
}else{
qqChat.setQqContent("未知消息");
}
list.add(qqChat);
qqChat = new QQChat();
}
Connection con = null;
PreparedStatement ps = null;
con = DBUtil.getConnection();
try {
for (QQChat q : list) {
sql = "insert into qq_record values(null,'"
+ q.getQqDate() + "','" + q.getQqTime() + "','"
+ q.getQqUser() + "','" + q.getQqContent() + "');";
ps = con.prepareStatement(sql);
ps.executeUpdate();
}
System.out.println("插入成功!");
} catch (SQLException e) {
//如果遇到出错的插入语句,则输出,查看问题在哪里,直接解决即可
System.out.println(sql);
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
} private static void processTxt() {
try {
//原始文档名为hdjg.txt
File file = new File("F:\\test\\hdjg.txt");
String str = null;
BufferedReader br = new BufferedReader(new FileReader(file));
PrintWriter out = new PrintWriter(new File("F:\\test\\999.txt"));
while ((str = br.readLine()) != null) {
//这个正则表达式用来匹配2015-02-10 16:02:50 张三
//如果是导出与一个人的聊天记录就不必用正则,但是我要导出的是群聊,所以要用正则
Pattern pattern = Pattern
.compile("\\d{4}\\-\\d{2}\\-\\d{2}\\s\\d{2}\\:\\d{2}\\:\\d{2}\\s.+");
Matcher matcher = pattern.matcher(str);
if (matcher.matches()) {
//每次输出时间姓名那一行之前都先输出一个换行
out.println();
//将有的文本中的两个空格替换成一个
out.print(str.replace(" ", " ")+" ");
} else {
/**
* 将聊天正文中的空格去掉,同时,有的正文中有单引号,这个会导致在数据插入时
* 出现问题,所以把正文中所有的单引号换成双引号
*/
out.print(str.replace(" ", "").replace("'", "\""));
}
}
out.close();
System.out.println("OK!");
} catch (IOException e) {
e.printStackTrace();
}
} }

DBUtil.java

public class DBUtil {
public static Connection getConnection() {
String username = "root";
String password = "admin";
String url = "jdbc:mysql://localhost:3306/qqchat";
Connection con = null;
try {
con = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
return con;
} public static void close(Connection con) {
try {
if(con!=null) con.close();
} catch (SQLException e) {
e.printStackTrace();
}
} public static void close(java.sql.PreparedStatement ps) {
try {
if(ps!=null) ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
} public static void close(ResultSet rs) {
try {
if(rs!=null) rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

QQChat.java

public class QQChat {

    private String qqDate;
private String qqTime;
private String qqUser;
private String qqContent;
public String getQqDate() {
return qqDate;
}
public void setQqDate(String qqDate) {
this.qqDate = qqDate;
}
public String getQqTime() {
return qqTime;
}
public void setQqTime(String qqTime) {
this.qqTime = qqTime;
}
public String getQqUser() {
return qqUser;
}
public void setQqUser(String qqUser) {
this.qqUser = qqUser;
}
public String getQqContent() {
return qqContent;
}
public void setQqContent(String qqContent) {
this.qqContent = qqContent;
} }

上面有一处用到了正则表达式,如果只导出与某一个人的聊天记录就没有必要用正则,如果导出的是好几年的群聊,正则就很有必要了。

把QQ聊天记录插入数据库中的更多相关文章

  1. 【hibernate spring data jpa】执行了save()方法 sql语句也执行了,但是数据并未插入数据库中

    执行了save()方法  sql语句也执行了,但是数据并未插入数据库中 解决方法: 是因为执行了save()方法,也执行了sql语句,但是因为使用的是 @Transactional 注解,不是手动去提 ...

  2. SqlBulkCopy将DataTable中的数据批量插入数据库中

    #region 使用SqlBulkCopy将DataTable中的数据批量插入数据库中 /// <summary> /// 注意:DataTable中的列需要与数据库表中的列完全一致.// ...

  3. 多线程查询数据,将结果存入到redis中,最后批量从redis中取数据批量插入数据库中【我】

    多线程查询数据,将结果存入到redis中,最后批量从redis中取数据批量插入数据库中 package com.xxx.xx.reve.service; import java.util.ArrayL ...

  4. SqlBulkCopy实现大容量数据快速插入数据库中

    一般情况下,我们手写sqlhelper类,在此类中定义一个数据插入到数据库的一个方法.将数据库连接密封在using()的语句中.using显示了Idispose接口.可以及时释放数据库连接资源.代码如 ...

  5. Java中获取刚插入数据库中的数据Id(主键,自动增长)

    public int insert(String cName, String ebrand, String cGender) { String sql = "insert into Clot ...

  6. jjava Date格式是 May 07 17:44:06 CST 2018,怎么插入数据库中的timestamp格式中

    首先 我来记录下错误 死在时间格式转换错误手里了 大致就是时间格式转化失败 java代码中的May 07 17:44:06 CST 2018  是这个格式转换为 数据库的 yyyy-MM-dd HH: ...

  7. mysql的load data,高速将文本文件,插入数据库中

    1语法 LOAD DATA [ LOW_PRIORITY | CONCURRENT ] [ LOCAL ] INFILE 'file_name.txt' [ REPLACE | IGNORE ] IN ...

  8. mysql循环插入数据库中数据。

    DELIMITER ;; CREATE PROCEDURE test_insert () BEGIN DECLARE i INT DEFAULT 1; WHILE i<100 DO insert ...

  9. pymysql中如何将动态的插入数据库中

    data = { ', 'name': 'zengsf', 'age': 20 } table = 'students' #获取到一个以键且为逗号分隔的字符串,返回一个字符串 keys = ', '. ...

随机推荐

  1. 降维(二)----Laplacian Eigenmaps

    降维(二)----Laplacian Eigenmaps 降维系列: 降维(一)----说说主成分分析(PCA)的源头 降维(二)----Laplacian Eigenmaps ----------- ...

  2. 【技术贴】破解Myeclipse10.7

    程序用的是http://www.cr173.com/soft/58306.html这个破解程序,是英文版的中文版.使用起来非常爽,看下面 使用期间关掉Myeclipse 期间的第三步,点击激活,此时会 ...

  3. xHtml+css学习笔记

    第一节 xHTML规范 *文档方面 -必须定义文档类型(DTD)和名字控件 *标签方面 -所有标签均要小写.关闭.合理嵌套.ID不能重复 -标签属性药有值,属性值要加印号且不能为空 -图片一定要加上a ...

  4. NODE.JS玩玩

    按一个网页的来,最好最后能到EXPRESS.JS. http://www.nodebeginner.org/index-zh-cn.html 这样就能对比DJANGO,看看两者的WEB框架,加深认识. ...

  5. Python还是很重要的,不能丢。学习IF和WHILE

    number = 23 guess = int(input('Enter an interger : ')) if guess == number: print('Congratulations, y ...

  6. HTML表单和验证事件

    1.表单验证<form></form> (1).非空验证(去空格) (2).对比验证(跟一个值对比) (3).范围验证(根据一个范围进行判断) (4).固定格式验证:电话号码, ...

  7. Android开源项目发现---Layout 篇(持续更新)

    1. achartengine 强大的图标绘制工具 支持折线图.面积图.散点图.时间图.柱状图.条图.饼图.气泡图.圆环图.范围(高至低)条形图.拨号图/表.立方线图及各种图的结合 项目地址:http ...

  8. nginx+gunicorn

    wsgi接口,使用gunicorn作为server,想在外层加nginx. 配置了 proxy_pass   http://127.0.0.1:9008; 访问报301. 参考gunicorn 官网配 ...

  9. bzoj2434

    利用了bzoj3172提到的性质,x串在y串中的出现的次数即为在fail树上以x结尾节点为根的子树中有多少个节点在y串上所以很明显我们要离线解决,我们先把询问按y分类存起来然后我们顺着操作顺序来,出现 ...

  10. bzoj1406

    这道题很有意思 我们解过线性同余方程,也解过同余方程 这个则是求x^2≡1 (mod p) 可以将问题转化为(x-1)(x+1)≡0 (mod p) 然后我们穷举一下p的约数i, 看i|x-1,p/i ...