找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

查看: 10459|回复: 10

[已解决] 请问下python如何实现对《》书名号里内容的正则获取?

1

主题

5

帖子

5

积分

贫民

积分
5
平凡的世界 发表于 2016-10-24 16:10:20 | 显示全部楼层 |阅读模式
    想做个小工具,获取例如《中国小说史略》这种书籍里提到的各种书名(ps:也就是《》书名号里的内容),目前暂定输入数据为txt格式,请问这个正则该怎么写呢?
回复

使用道具 举报

1419

主题

1891

帖子

291

积分

侠客

积分
291

最佳新人热心会员默默耕耘

whydo1 发表于 2016-10-24 17:22:20 | 显示全部楼层
import re
txt = '《中国小说史略》'
f = re.findall('《(.*?)》',txt)

print(f)
python3.4.4, win10
回复 支持 1 反对 0

使用道具 举报

1

主题

5

帖子

5

积分

贫民

积分
5
平凡的世界  楼主| 发表于 2016-10-25 15:52:52 | 显示全部楼层
whydo1 发表于 2016-10-24 17:22
import re
txt = '《中国小说史略》'
f = re.findall('《(.*?)》',txt)

感谢您。按照您给的正则昨天写出来大概,今天又在调bug。终于把数据获取的工作完成了。
#coding:utf-8
import re
# 目的txt,以gbk编码
f=open('D:\\1.txt', 'r')
# 实际使用txt,以utf-8编码
f2=open('D:\\2.txt', 'w')
# 实际使用txt,以utf-8编码
# 在这里要注意decode方式,我试了GBK GB2312 GB18030,发现GB18030的范围最大,有些字符集
# GBK GB2312无法解析,但是GB18030能解析
f2.write(f.read().decode('GB18030').encode('utf-8'))
# 最后生成书名号《》里的txt
f3=open('D:\\3.txt', 'w')
for line in open('D:\\2.txt') :
    list = re.findall('《(.*?)》',line)
    for i in list:
        f3.write(i)
        f3.write("\n")
f3.close()

    其中碰到的最大的坑还是字符集转换问题,比如我下载的中国小说史略.txt,之前按行循环有些行无法输出,发现是编码方式不对。win默认文本文档编码的是GB2312,但是txt文档每一行可能会有有奇奇怪怪的编码方式(通过chardet package发现的这个问题,因为这个问题找了一上午),试了三种编码,最后还是GB18030所包含范围最广。
   衷心感谢!@whydo1   
    不过现在还有一个很古怪的问题,就是每一个txt文档在执行循环的时候,最后面几行无法被获取到。
    比如说1000行的txt,可能只会循环检测操作的前面980行。谁知道为什么么?
    测试代码如下:
#coding:utf-8
import re
f=open('D:\\1.txt', 'r')
f2=open('D:\\2.txt', 'w')
f2.write(f.read().decode('GB18030').encode('utf-8'))
f3=open('D:\\3.txt', 'w')
for line in open('D:\\2.txt') :
    print(line)

其中,用的python版本是2.7。 谁能帮忙瞅瞅嘛?
回复 支持 反对

使用道具 举报

0

主题

18

帖子

18

积分

贫民

积分
18
kushao1267 发表于 2016-10-25 16:44:20 | 显示全部楼层
首先确定你txt里有1000行,一般for i in list不会出这样的错误
回复 支持 反对

使用道具 举报

1

主题

5

帖子

5

积分

贫民

积分
5
平凡的世界  楼主| 发表于 2016-10-25 17:01:00 | 显示全部楼层
kushao1267 发表于 2016-10-25 16:44
首先确定你txt里有1000行,一般for i in list不会出这样的错误

举个例子,我下载了两个txt文件获得的结果都是这样。我上面的回答里有测试代码。您能测试下么?
回复 支持 反对

使用道具 举报

0

主题

18

帖子

18

积分

贫民

积分
18
kushao1267 发表于 2016-10-25 17:25:56 | 显示全部楼层
平凡的世界 发表于 2016-10-25 17:01
举个例子,我下载了两个txt文件获得的结果都是这样。我上面的回答里有测试代码。您能测试下么? ...

说白就是你下了一本txt,然后给它转编码存到2.txt,现在用这段代码:
f2=open('D:\\2.txt', 'w')
for line in open('D:\\2.txt') :
    print(line)

只print出980行对吧?
回复 支持 反对

使用道具 举报

1419

主题

1891

帖子

291

积分

侠客

积分
291

最佳新人热心会员默默耕耘

whydo1 发表于 2016-10-25 19:58:02 | 显示全部楼层
findall可以处理多行, 所以其实不需要用循环.
python3.4.4, win10
回复 支持 反对

使用道具 举报

0

主题

4

帖子

4

积分

贫民

积分
4
sy123 发表于 2016-10-25 22:26:30 | 显示全部楼层
《(.*?)》
回复

使用道具 举报

1

主题

5

帖子

5

积分

贫民

积分
5
平凡的世界  楼主| 发表于 2016-10-25 23:50:06 | 显示全部楼层
kushao1267 发表于 2016-10-25 17:25
说白就是你下了一本txt,然后给它转编码存到2.txt,现在用这段代码:
f2=open('D:\\2.txt', 'w')
for lin ...

对的,就是这样,末尾几行在for循环处理时丢失,但是转码到2.txt时内容都在的
回复 支持 反对

使用道具 举报

1

主题

5

帖子

5

积分

贫民

积分
5
平凡的世界  楼主| 发表于 2016-10-26 11:02:28 | 显示全部楼层
whydo1 发表于 2016-10-25 19:58
findall可以处理多行, 所以其实不需要用循环.

谢谢。
优化了下,删除了循环,直接一次性读取txt文件所有内容,如下:
#coding:utf-8
import re
# 目的txt,以gbk编码
f=open('D:\\原GBK编码的txt文件名.txt', 'r')
# 实际使用txt,以utf-8编码
f2=open('D:\\utf-8编码的txt文件名(和原txt内容一致,只是编码方式不同).txt', 'w')
# 实际使用txt,以utf-8编码
# 在这里要注意decode方式,我试了GBK GB2312 GB18030,发现GB18030的范围最大,有些字符集
# GBK GB2312无法解析,但是GB18030能解析
f2.write(f.read().decode('GB18030').encode('utf-8'))
f2.close()
f.close()
# 最后生成书名号《》里的txt
f3=open('D:\\书名号内容的txt文件名.txt', 'w')
f4=open('D:\\utf-8编码的txt文件名.txt').read()
list = re.findall('《(.*?)》',f4)
for i in list:
    f3.write(i)
    f3.write("\n")
f3.close()
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表