python+正则表达式提取“参考文献”中的作者名,发表日期等信息

来源:互联网 发布:网络协议 编辑:程序博客网 时间:2024/05/17 17:59

此文章为作者原创,如转载请先联系作者。

一、任务描述

如下图(excel表截图,输出示例.xlsx):

这里写图片描述

现需要从上图V列“参考文献”里提取出从N列到U列(除Q列以外,Q列文献期的内容不存在)

二、思考

第一步,观察数据

以参考文献下的第一个数据为例:

这里写图片描述

首先观察到双引号里的内容是“文献题目”,“1990”是文献年,”Acker, Joan”是文献作者,“Gender and Society”是文献期刊,4是文献卷,139-58中139是文献起始页,58是页数,则文献结束页就是197。

当然这是理想的情况,扫视一遍数据,发现还是有很多不属于这个格式的。

像下面几种数据


Acker, Joan. 2006. Class Questions: Feminist Answers.
Lanham, MD: Rowman & Littlefíeld.


这样的数据大概有两三个。他们是没有文献卷和文献起始页和页数的,有的文献题目还不在双引号内。


Charles, Maria and David B. Grusky. 2007. “Egalitari-
anism and Gender Inequality.” Pp. 327-42 in The
Inequality Reader: Contemporary and Foundational
Readings in Race, Class, and Gender, edited by D.
Grusky and S. Szelényi. Boulder, CO: Westview Press.


这样的完全不同格式的数据只有这一个。

总之,大部分数据还是符合最开始的那种格式,大体把数据的当做第一种,之后为了让程序能够运行,再稍作处理。

第二步,构思提取方法。

这样的分词工具在github上有很多开源的。

如:用于中文分词的jieba(https://github.com/hosiet/jieba)
用于中英文等多种语言的Stanford corenlp(https://github.com/stanfordnlp/CoreNLP)
后面这个我测试了一下,识别能力真的特别强,功能强大,用于自然语言处理比较多,虽然说我这个任务用不着。(在线测试网址:corenlp.run)——以第一条数据为例
这里写图片描述
这里写图片描述

特别提醒:corenlp-python接口不支持windows系统(我也是试了很久发现不支持)

思路:

re是python的一个模块

  1. 对excel的操作是用pandas模块

    • re.findall提取双引号之间的内容——得到文献题目(不考虑特殊数据,程序正常运行)
    • re.sub想办法去除双引号及双引号里的内容,得到余下部分内容text
    • re.sub(“\D”,”“, string)提取余下部分内容text中所有的数字,取前四个数字即文献年。
    • 得到文献年第一个数字在余下部分内容text中的索引,文献年之前的内容都是作者名,对text进行切片即可
    • 提取文献年后的内容(对text进行切片),得到的内容finalText包括文献期刊和文献起始页和页数的(如果有的话)
    • re.sub(“\d”, “”,finalText)提取除数字以外的字符串即文献期刊(如果有的话,可以不用判断,没有就不会输出)
    • 由于前面提到有几个特殊的数据,(他们是没有文献卷和文献起始页和页数的)所以这里在提取数字的时候要进行判断一下
    • bool(re.search(r’\d’, finalText))判断一下finalTetx里是否是数字
    • 如果有的话,对finalText进行re.split(r’[:,\s])’切割,得到一个列表,列表的后两项即是“4”,“139-58 ”(以第一个数据为例子)
    • “139-58 ”可以用spit(”-“)分离

以上为大体思路,事实上,才运行时,由于之前提到的有一些特殊数据,导致了程序不能运行,只能通过一些条件处理,把它过滤。

最终结果为如下:

这里写图片描述

完整代码如下:

#encoding=utf-8import pandas as pdimport redf = pd.read_excel("./data/输出示例.xlsx")rf = df["参考文献"]for i in range(0,90):    # 提取T列文献题目    t = re.findall('"([^"]+)"', rf.iat[i])    T = ','.join(t)    df.iat[i, 19] = T    #去除双引号中的内容    text = re.sub('"([^"]+)"', "", rf.iat[i])    # 提取O列文献年    totalCount = re.sub("\D", "", text)    newNumber = totalCount[0:4]    df.iat[i, 14] = newNumber    #提取N列文献作者    opsition = text.index(newNumber)    author = text[0:opsition]    df.iat[i, 13] = author    #提取文献年后的内容(此时双引号及双引号里的内容也没有)    finalText = text[opsition + 1 + len(newNumber):]    #提取U列文献期刊,如果有的话    journal = re.sub("\d", "", finalText)    df.iat[i, 20] = journal    if bool(re.search(r'\d', finalText)):        finalNumber = re.split(r'[: ,\s]', finalText)        # print(finalNumber)        # 提取P列文献卷        last1 = finalNumber[-2]        try:            float(last1)            df.iat[i, 15] = last1        except ValueError:            df.iat[i, 15] = 0        #提取文献起始页和结束页        last2 = finalNumber[-1]        if bool(re.search(r'\d', last2)):            start = last2.split("-")[0]            end1 = last2.split("-")[-1]            end2 = int(end1.strip(".")) + int(start)            df.iat[i, 17] = start            df.iat[i, 18] = end2        else:            pass    else:        passdf.to_excel("./data/test.xlsx")
原创粉丝点击