如何读取.bib文件为文本并将其字段分开以达到计量目标?

时间:2019-01-04 17:24:47

标签: matlab

我有一个.bib文件,并且我正在使用MATLAB从中提取不同的字段。目标是计算不同的文献索引,例如h-index。 我已经尝试过textscan(),但是因为每个文章的字段都不相同,所以它并不是全部工作。 围兜如下:

@article{LIM20072054,
title = "Prevention of cardiovascular disease in high-risk individuals in low-income and middle-income countries: health effects and costs",
journal = "The Lancet",
volume = "370",
number = "9604",
pages = "2054 - 2062",
year = "2007",
issn = "0140-6736",
doi = "https://doi.org/10.1016/S0140-6736(07)61699-7",
url = "http://www.sciencedirect.com/science/article/pii/S0140673607616997",
author = "Stephen S Lim and Thomas A Gaziano and Emmanuela Gakidou and K Srinath Reddy and Farshad Farzadfar and Rafael Lozano and Anthony Rodgers",
abstract = "Summary}

我尝试使用fgetl()获取行,但是我需要一次读取所有文件,也许可以很好地{与}分隔文章,是否有人在我们知道如何提取具有不同字段的无格式文本的更好的主意?字段名称? 这是第一个代码

a = fopen('C:\Users\u3f\Downloads\a.bib');
textI='@article{%s title = %q %*s %*s %*s %*s year = %q %*s %*s %*s %*s abstract = %q %*s';
C = textscan(a,textI,'Delimiter','\n')
fclose(a)

2 个答案:

答案 0 :(得分:1)

这可能需要一些工作,但应该可以为您带来所需的收益。

想法是逐行扫描,首先查找以@article{开头的行。然后,它创建一个块并添加以下行,直到找到以}结尾的行(请注意,如果您的bibtex具有以}结尾的字段,则可能需要进行一些修改)。

找到一个块的末尾时,它将转换为一个结构,在bibtex上的每个条目都变成一个字段。条目的关键字也被添加为名为name的字段。处理完所有块后,您将拥有一个名为entryList的单元,每个bibtex条目具有一个结构。

请记住,对于复杂的条目,您可能需要执行更复杂的文本解析才能使所有功能正常工作。

a = fopen('a.bib');
insideEntry = false;
currEntry = {};
entryList = {};
while(~feof(a))
  lin = fgetl(a); % Pull one line at a time
  if(insideEntry) % If you are inside an @article block
    currEntry = [currEntry lin]; % Append line
    if(regexp(lin, '$*}')) % Check for the end of a block
      insideEntry = false;
      entryname = extractBetween(currEntry{1}, '@article{',',');
      entryStruct = struct;
      entryStruct.name = entryname{1};
      for it = 2:length(currEntry)
        sepLine = strsplit(currEntry{it}, '=');
        if(length(sepLine) == 2)
          fieldName = strrep(strtrim(sepLine{1}),'-','_'); % Fix the keyword name (so it can be a field in a structure)
          sepLine{2} = regexprep(sepLine{2},'$*[",}]',''); % Fix end of entry
          sepLine{2} = regexprep(sepLine{2},'^[ "{]',''); % Fix start of entry
          entryStruct.(fieldName) = sepLine{2}; % Assign text to the struct field
        end
      end
      entryList{end+1} = entryStruct; % Append to the entry list
      currEntry = {};
    end
  elseif(contains(lin, '@article{')) % Look for @article block start line
    insideEntry = true;
    currEntry = [currEntry lin];
  end
end
fclose(a);

对于您提供的示例bibtex,应生成:

entryList{1}

ans = 

struct with fields:

    name: 'LIM20072054'
   title: 'Prevention of cardiovascular disease in high-risk individuals in low-income and middle-income countries: health effects and costs'
 journal: 'The Lancet'
  volume: '370'
  number: '9604'
   pages: '2054 - 2062'
    year: '2007'
    issn: '0140-6736'
     doi: 'https://doi.org/10.1016/S0140-6736(07)61699-7'
     url: 'http://www.sciencedirect.com/science/article/pii/S0140673607616997'
  author: 'Stephen S Lim and Thomas A Gaziano and Emmanuela Gakidou and K Srinath Reddy and Farshad Farzadfar and Rafael Lozano and Anthony Rodgers'
abstract: 'Summary'

答案 1 :(得分:0)

您可以使用BibTeX解析库为您读取文件并将其上载到数据结构中。这样一来,您就不必使用Matlab提供的基本I / O功能(不支持内置格式的文件)对这些文件进行低级解析。

Matlab可以使用Java库,因此您可以使用jbibtex library

(这里是details on how to call Java libraries from Matlab。)