正则表达式解析引用问题

Regex parsing citation issue

我正在尝试从 PDF 中提取引文。我确认我的正则表达式适用于 Rubular here but when I test my code on a real PDF it spits out some oddly spaced and wrong information. How can I fix this regex so it only extracts APA paper citations (the ones in the references section, not in-text). The 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

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

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

我来拍一张:

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

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

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

参见live demo

这允许在引用中换行,除了在期刊文本中。

编辑

试试这个,我试过这样修改它,以匹配您评论中的位置。

^(?<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&.,'’] 添加一些符号 字符class,如果有更多的字符,可以出现在 这部分参考。
    • \((?<year>\d{4})\) - year 分组捕获数字,如果它们在括号内,
    • (?<title>[^()]+?[?.!])\s* - title 组捕获一个或多个任意字符,但不包括括号,后跟字符 从字符 class [?.!],我使用 [^()] 因为在测试期间 我发现它可以防止正则表达式进行多行无效匹配, 同样重要的是,这部分匹配受限于 替代品,没有它们,它会给出无效的结果,所以它 不匹配独立的独立部分,
  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)) - 这个替代匹配期刊标题 nad 问题。 jurnal组 匹配以大写字母开头,后跟 不是点(不是 .),带有惰性量化(与 必须成功),后跟逗号。 [^.] 是 used,因为有些期刊的标题包含逗号,我不能用 [^,] 这是我的第一个想法,所以我限制了这个匹配 与点分开,它总是出现在参考的末尾, 不情愿的量化,它允许放弃已经匹配 用于后续匹配的片段(最多点)。 issue组 将数字与下一个逗号或点之前的某些内容匹配,如果是 后跟逗号和数字(页码)或点和单词 已检索,
    • (?:In\s*(?<editors>[^()]+))\(Eds?\.\),\s*(?<book>[^().]+) - 这部分匹配参考编辑的书,editor 组匹配 除了 paratheses 之外的任何内容(直到 Eds. 或 Ed. 关键词)之后 由带有页码的下一个段落限制的标题或 点
    • (?:[^():]+:[^().]+\.) - 此部分仅用于将参考文献与有关出版商和出版地点的信息相匹配, 之前的方法是在整个替代部分使用 ? 没有效果,因为它也匹配的地方 应匹配另一种选择,
    • (?:Retrieved|Paper presented)) - 这部分用于匹配引用在线资源或演示文稿等的参考资料。我 可以用其他关键字扩展,

旧尝试

如果您只需要作者、日期、标题和有问题的期刊,您可以尝试:

^(?<author>(?:(?!$)[A-Za-z\s&.,'’])+)\((?<year>\d{4})\)\.?\s*(?<title>[^?.!]+?[.?!])\s*(?!\s*Retrieved)(?:(?:(?<jurnal>(?:(?!^[A-Z])[^,])+?),\s*(?<issue>\d+)))

DEMO rebular
DEMO regex101

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

^(?<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

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