正则表达式解析引文问题

时间:2015-09-25 04:55:59

标签: regex pdf ruby-2.0

我正在尝试从PDF中提取引文。我确认我的正则表达式使用了Rubular here但是当我在真实的PDF上测试我的代码时,它会吐出一些奇怪的间隔和错误的信息。如何修复此正则表达式,以便它只提取APA论文引用(参考部分中的那些,而不是文本中)。 APA Examples可能有用。我想从研究论文中获取参考资料。 如果您需要更多详细信息,请告诉我们。这个答案可以接受多个正则表达式,但我需要能够提取作者,标题,日期和日记。如果它对任何人都有帮助,我的尝试就在下面:

require 'pdf-reader'
io = open('https://vhil.stanford.edu/pubs/2007/yee-proteus-effect.pdf')
out=open('dump.txt',"w")
reader = PDF::Reader.new(io)

reader.pages.each do |page|
    /([a-zA-Z.,&\s]+?)(\(\d+\)).([\sa-zA-Z,:\n\t]+).([\sa-zA-Z,]+).([\sa-zA-Z,]+)/.match(page.text){|m|
        puts "===CITATION===="
        puts "author: "+m[0].to_str.gsub(/\n\r\t/,'')
        puts "title: "+m[2].to_str.gsub(/\n\r\t/,'')
        puts "date: "+m[1].to_str.gsub(/\n\r\t/,'')
        puts "journal: "+m[3].to_str.gsub(/\n\r\t/,'')
  }
  #puts page.raw_content
end
puts"\n\n\n=======\n\n\n======"
puts reader.pages.last

更多示例(回复评论)herehere 整篇论文 here

为了得到这些例子,我在foreach循环中运行了out.puts page.text。然后我将大块文本复制到Rubular中并使用我原来的正则表达式进行测试(上图)。

3 个答案:

答案 0 :(得分:5)

修改

尝试这个,我尝试以这种方式修改它,以匹配评论中的位置。

^(?<author>[A-Z](?:(?!$)[A-Za-z\s&.,'’])+)\((?<year>\d{4})\)\.?\s*(?<title>[^()]+?[?.!])\s*(?:(?:(?<jurnal>(?:(?!^[A-Z])[^.]+?)),\s*(?<issue>\d+)[^,.]*(?=,\s*\d+|.\s*Ret))|(?:In\s*(?<editors>[^()]+))\(Eds?\.\),\s*(?<book>[^().]+)|(?:[^():]+:[^().]+\.)|(?:Retrieved|Paper presented))

Rebular DEMO
Regex101 DEMO

最后一部分(?:Retrieved|Paper presented)可以使用标题后可能出现的其他单词进行扩展。

这个正则表达式包含两个主要部分:

  1. ^(?<author>[A-Z](?:(?!$)[A-Za-z\s&.,'’])+)\((?<year>\d{4})\)\.?\s*(?<title>[^()]+?[?.!])\s* 匹配作者,日期和标题的共享部分:

    • (?<author>[A-Z](?:(?!$)[A-Za-z\s&.,'’])+) - author组,仅从单词的首字母开始匹配 字母,以避免在文本的某处匹配,点头 引用,后跟字母,空格,一些标点符号, 您可以随时向[A-Za-z\s&.,'’]添加一些符号 字符类,如果有更多字符,可以在其中出现 这部分参考。
    • \((?<year>\d{4})\) - year组捕获数字,如果它们在括号内,
    • (?<title>[^()]+?[?.!])\s* - title组捕获一个或多个字符,但不是括号,后跟字符 从字符类[?.!]开始,我使用[^()]因为在测试期间 我发现它可以阻止多行无效匹配的正则表达式, 同样重要的是,这部分匹配受到限制 替代品,如果没有它们,它会产生无效结果,所以它 不是独立匹配的独立部分,
  2. (?:(?:(?<jurnal>(?:(?!^[A-Z])[^.]+?)),\s*(?<issue>\d+)[^,.]*(?=,\s*\d+|.\s*Ret))|(?:In\s*(?<editors>[^()]+))\(Eds?\.\),\s*(?<book>[^().]+)|(?:[^():]+:[^().]+\.)|(?:Retrieved|Paper presented))替代其他内容。

    • (?<jurnal>(?:(?!^[A-Z])[^.]+?)),\s*(?<issue>\d+)[^,.]*(?=,\s*\d+|.\s*Ret)) - 这个替代匹配jurnal title nad问题。 jurnal小组 匹配以大写字母开头的片段,后跟 不是点(不是.),懒惰量化(匹配就像 它必须成功),然后是逗号。 [^.]是。{ 使用,因为一些昼夜标题包含逗号,我无法使用 [^,]这是我的第一个想法,所以我重新考虑了这一点 有点的部分,总是在参考的末尾出现, 不情愿的量化,它放弃了已经匹配的放弃 用于跟踪匹配的片段(最多点)。 issue组。(?:In\s*(?<editors>[^()]+))\(Eds?\.\),\s*(?<book>[^().]+) 匹配数字与某些内容,直到下一个逗号或点,如果是 后跟逗号,数字(页码)或点和字 retrived,
    • editor - 此部分匹配对已编辑图书,(?:[^():]+:[^().]+\.)群组匹配的引用 任何东西,但不是paratheses(由Eds。或Ed。关键词)跟随 由标题限制的下一个paratheses与页码或 点
    • ? - 此部分仅用于将参考文献与有关出版商和出版地的信息进行匹配, 以前的approuch在整个替代品部分使用(?:Retrieved|Paper presented)) 没有效果,因为它也适用于那些地方 另一种选择应该匹配,
    • ^(?<author>(?:(?!$)[A-Za-z\s&.,'’])+)\((?<year>\d{4})\)\.?\s*(?<title>[^?.!]+?[.?!])\s*(?!\s*Retrieved)(?:(?:(?<jurnal>(?:(?!^[A-Z])[^,])+?),\s*(?<issue>\d+))) - 此部分用于匹配引用的在线来源或演示文稿等 可以使用其他关键字进行扩展,
  3. 旧尝试

    如果您只需要作者,日期,标题和日期问题,可以尝试使用:

    ^(?<author>(?:(?!$)[A-Za-z\s&.,'’])+)\((?<year>\d{4})\)\.?\s*(?<title>[^?.!]+?[.?!])\s*(?:(?<retrieved>[Rr]etrieved.+)|(?:(?:(?<jurnal>(?:(?!^[A-Z])[^,])+?),\s*(?<issue>\d+)))|\s*In(?<editors>[^\(]+)\(Eds\.\),(?<book>[^.()]+))?
    

    DEMO rebular
    DEMO regex101

    但是,如果您对编辑过的书籍感兴趣,请尝试:

    <Bob xmlns="gdfgdfg">
        <Alice>
            <Rob>dsdsdsd</Rob>
            <Mike>fdgdfg</<Mike>>
            <Pete>dfgdfg</Pete>
            <UsageList>
                <Client id="1">
                    <Usage cat1="100002" dog1="1000020000" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:29:29 +0100" endTime="24-09-2015 12:29:29 +0100"
                        ant1="aaaaa" snake1="1" errcode="1" />
                    <Usage cat1="1000230" dog1="10000560000" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:29:29 +0100" endTime="24-09-2015 12:29:29 +0100"
                        ant1="aaaaa" snake1="1" errcode="1" />
                    <Usage cat1="100001" dog1="4656545465" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:29:29 +0100" endTime="24-09-2015 12:29:29 +0100"
                        ant1="aaaaa" snake1="1" errcode="0" />
                    <Usage cat1="100001" dog1="4656545465" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:29:44 +0100" endTime="24-09-2015 12:29:44 +0100"
                        ant1="aaaaa" snake1="1" errcode="0" />
                    <Usage cat1="100002" dog1="1000020000" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:29:44 +0100" endTime="24-09-2015 12:29:44 +0100"
                        ant1="aaaaa" snake1="1" errcode="1" />
                    <Usage cat1="100000" dog1="10000000000" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:24:28 +0100" endTime="24-09-2015 12:24:28 +0100"
                        ant1="aaaaa" snake1="1" errcode="1" />
                </Client>
                <Client id="2">
                    <Usage cat1="100003" dog1="465546" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:29:44 +0100" endTime="24-09-2015 12:29:44 +0100"
                        ant1="aaaaa" snake1="1" errcode="0" />
                    <Usage cat1="100005" dog1="10000000000" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:29:44 +0100" endTime="24-09-2015 12:29:44 +0100"
                        ant1="aaaaa" snake1="1" errcode="1" />
                    <Usage cat1="100003" dog1="465546" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:29:29 +0100" endTime="24-09-2015 12:29:29 +0100"
                        ant1="aaaaa" snake1="1" errcode="0" />
                    <Usage cat1="100004" dog1="1002300000" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:29:29 +0100" endTime="24-09-2015 12:29:29 +0100"
                        ant1="aaaaa" snake1="1" errcode="1" />
                    <Usage cat1="100005" dog1="10000000000" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:29:29 +0100" endTime="24-09-2015 12:29:29 +0100"
                        ant1="aaaaa" snake1="1" errcode="1" />
                    <Usage cat1="100004" dog1="1002300000" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:29:44 +0100" endTime="24-09-2015 12:29:44 +0100"
                        ant1="aaaaa" snake1="1" errcode="1" />
                </Client>
                <Client id="3">
                    <Usage cat1="100007" dog1="5463453" fish1="1"
                        mouse1="3" beginTime="24-09-2015 12:29:44 +0100" endTime="24-09-2015 12:29:44 +0100"
                        ant1="aaaaa" snake1="1" errcode="1" />
                    <Usage cat1="100006" dog1="122113231" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:29:29 +0100" endTime="24-09-2015 12:29:29 +0100"
                        ant1="aaaaa" snake1="1" errcode="1" />
                    <Usage cat1="100007" dog1="5463453" fish1="1"
                        mouse1="3" beginTime="24-09-2015 12:29:29 +0100" endTime="24-09-2015 12:29:29 +0100"
                        ant1="aaaaa" snake1="1" errcode="1" />
                    <Usage cat1="100006" dog1="122113231" fish1="1"
                        mouse1="2" beginTime="24-09-2015 12:29:44 +0100" endTime="24-09-2015 12:29:44 +0100"
                        ant1="aaaaa" snake1="1" errcode="1" />
                </Client>
            </UsageList>
        </Alice>
    </Bob>
    

    DEMO rebular
    DEMO regex101

    正则表达式都会将相关值捕获到命名组中:作者,年份,标题等。

答案 1 :(得分:0)

我会开枪:

/^(.+?)\s*(\(\d.+?\))\.?\s*(.+?)\.\s*(.+?),\s\d/m

答案 2 :(得分:0)

这似乎适用于(之前)链接文档中的所有引用:

^([\S\s]*?)\s*\((\d{4})\)\.?\s*([\S\s]*?\??)(?:(?:[.]|(?<=\? ))(?=(?:[^.]|[.](?:[\d,]|com|pdf|html?))*?[. ]*$)\s*|(?= Retrieved ))(.*)?

请参阅live demo

这允许在引文中添加换行符,除了日记文本中的