как прочитать файл .bib как текст и отделить его поле для библиометрических целей? - PullRequest
0 голосов
/ 04 января 2019

У меня есть файл .bib, и я использую MATLAB для извлечения из него различных полей. цель состоит в том, чтобы вычислить различные библиометрические индексы, такие как h-индекс. я пробовал textcan (), но потому что поля не являются одинаковыми для каждой статьи, это не вся работа. нагрудник выглядит следующим образом:

@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 голосов
/ 07 января 2019

Вы можете использовать библиотеку синтаксического анализа BibTeX, чтобы прочитать файл и передать его в структуры данных. Таким образом, вам не нужно выполнять низкоуровневый анализ этих файлов самостоятельно, используя базовые функции ввода-вывода, которые Matlab предоставляет для форматов файлов, для которых он не имеет встроенной поддержки.

Matlab может использовать библиотеки Java, поэтому вы можете использовать библиотеку jbibtex .

(А вот подробности о том, как вызывать библиотеки Java из Matlab .)

0 голосов
/ 05 января 2019

Это может потребовать немного работы, но должно дать вам то, что вы хотите.

Идея состоит в том, чтобы сканировать построчно, сначала ища строку, которая начинается с @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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...