Удаление определенной записи из файла bibtex на основе ключа цитирования с использованием Python
Как удалить конкретную запись из файла bibtex на основе ключа цитирования с помощью Python? Я в основном хочу функцию, которая принимает два аргумента (путь к файлу bibtex и ключ цитирования) и удаляет запись, которая соответствует ключу из файла. Я играл с регулярными выражениями, но не увенчался успехом. Я также немного искал парсеры bibtex, но это кажется излишним. В приведенной ниже функции скелета решающая часть content_modified =
,
def deleteEntry(path, key):
# get content of bibtex file
f = open(path, 'r')
content = f.read()
f.close()
# delete entry from content string
content_modified =
# rewrite file
f = open(path, 'w')
f.write(content_modified)
f.close()
Вот пример файла bibtex (с пробелами в аннотации):
@article{dai2008thebigfishlittlepond,
title = {The {Big-Fish-Little-Pond} Effect: What Do We Know and Where Do We Go from Here?},
volume = {20},
shorttitle = {The {Big-Fish-Little-Pond} Effect},
url = {http://dx.doi.org/10.1007/s10648-008-9071-x},
doi = {10.1007/s10648-008-9071-x},
abstract = {The big-fish-little-pond effect {(BFLPE)} refers to the theoretical prediction that equally able students will have lower academic
self-concepts in higher-achieving or selective schools or programs than in lower-achieving or less selective schools or programs,
largely due to social comparison based on local norms. While negative consequences of being in a more competitive educational
setting are highlighted by the {BFLPE}, the exact nature of the {BFLPE} has not been closely scrutinized. This article provides
a critique of the {BFLPE} in terms of its conceptualization, methodology, and practical implications. Our main argument is that
of the {BFLPE.}},
number = {3},
journal = {Educational Psychology Review},
author = {Dai, David Yun and Rinn, Anne N.},
year = {2008},
keywords = {education, composition by performance, education, peer effect, education, school context, education, social comparison/big-fish{\textendash}little-pond effect},
pages = {283--317},
file = {Dai_Rinn_2008_The Big-Fish-Little-Pond Effect.pdf:/Users/jpl2136/Documents/Literatur/Dai_Rinn_2008_The Big-Fish-Little-Pond Effect.pdf:application/pdf}
}
@book{coleman1966equality,
title = {Equality of Educational Opportunity},
shorttitle = {Equality of educational opportunity},
publisher = {{U.S.} Dept. of Health, Education, and Welfare, Office of Education},
author = {Coleman, James},
year = {1966},
keywords = {\_task\_obtain, education, school context, soz. Ungleichheit, education}
}
РЕДАКТИРОВАТЬ: Вот решение, которое я придумал. Он не основан на сопоставлении всей записи bibtex, а ищет все начала @article{dai2008thebigfishlittlepond,
и затем удаляет соответствующую запись, разрезая контекстную строку.
content_keys = [(m.group(1), m.start(0)) for m in re.finditer("@\w{1,20}\{([\w\d-]+),", content)]
idx = [k[0] for k in content_keys].index(key)
content_modified = content[0:content_keys[idx][1]] + content[content_keys[idx + 1][1]:]
1 ответ
Как отметил в комментарии Бени Чернявский-Паскин, вам придется полагаться на тот факт, что ваши записи BibTex будут начинаться и заканчиваться сразу после начала строки (без каких-либо пробелов или пробелов). Тогда вы можете сделать это:
pattern = re.compile(r"^@\w+\{"+key+r",.*?^\}", re.S | re.M)
content_modified = re.sub(pattern, "", content)
Обратите внимание на два модификатора. S
делает .
разрывы строк M
марки ^
совпадать в начале строки.
Если вы не можете полагаться на этот факт, то формат BibTex просто не является обычным языком (так как он позволяет вкладывать {}
который должен быть посчитан для правильных результатов. Существуют разновидности регулярных выражений, которые могут по-прежнему делать эту задачу возможной (с использованием группы рекурсии или балансировки), но я думаю, что Python не поддерживает ни одну из этих функций. Следовательно, вам на самом деле придется использовать синтаксический анализатор BibTex (который, я думаю, также сделает ваш код намного более нестабильным).