PubMed参考文献转NLM格式工具开发遇阻,求代码排查修复
需求说明
需将PubMed获取的参考文献转换为符合以下规则的NLM(数值型)格式:
- 作者姓名最多列3位,超出则用et al.
- 作者不足3位全列;2位作者用and连接
- 文献标题采用句首大写格式(sentence case)
- 使用PubMed期刊缩写
- 期刊名称不使用斜体
- 期刊名称与年份间加句号
- 仅保留出版年份,不含日、月
- 年份后加分号,卷号、页码前无空格
- 页码范围用连字符,末尾加句号(如
26-28.) - 页码不缩写
- 所有参考文献以句号结尾
- 不使用粗体和斜体
转换示例
示例1
PubMed参考文献:
McInnes IB, Asahina A, Coates LC, Landewé R, Merola JF, Ritchlin CT, Tanaka Y, Gossec L, Gottlieb AB, Warren RB, Ink B, Assudani D, Bajracharya R, Shende V, Coarse J, Mease PJ. Bimekizumab in patients with psoriatic arthritis, naive to biologic treatment: a randomised, double-blind, placebo-controlled, phase 3 trial (BE OPTIMAL). Lancet. 2023 Jan 7;401(10370):25-37. doi: 10.1016/S0140-6736(22)02302-9. Epub 2022 Dec 6. PMID: 36493791.
转换后格式:
McInnes IB, Asahina A, Coates LC, et al. Bimekizumab in patients with psoriatic arthritis, naïve to biologic treatment: a randomised, double-blind, placebo-controlled, phase 3 trial (BE OPTIMAL). Lancet. 2023;401(10370):25-37.
示例2
PubMed参考文献:
Reich K, Warren RB, Lebwohl M, Gooderham M, Strober B, Langley RG, Paul C, De Cuyper D, Vanvoorden V, Madden C, Cioffi C, Peterson L, Blauvelt A. Bimekizumab versus Secukinumab in Plaque Psoriasis. N Engl J Med. 2021 Jul 8;385(2):142-152. doi: 10.1056/NEJMoa2102383. Epub 2021 Apr 23. PMID: 33891380.
转换后格式:
Reich K, Warren RB, Lebwohl M, et al. Bimekizumab versus secukinumab in plaque psoriasis. N Engl J Med. 2021;385(2):142-152.
原代码问题分析
原代码存在以下关键问题:
- 正则表达式错误:命名组语法错误(
(?P\<authors\>)应为(?P<authors>)),匹配逻辑混乱,未正确处理字段分隔符,也未忽略年份后的月日信息 - 语法错误:注释符号错误(
\#应为#),代码缩进不一致,主程序入口写错(if name == "main"应为if __name__ == "__main__")且代码挤在一行 - 功能缺失:未实现标题句首大写转换,
et al漏了末尾句号,未严格遵循NLM格式的标点规则
修正后的代码
import re def sentence_case(title): # 实现标题句首大写,保留括号内专有名词格式 if not title: return "" parts = re.split(r'(\(.*?\))', title) processed_parts = [] for part in parts: if part.startswith('(') and part.endswith(')'): processed_parts.append(part) else: lower_part = part.lower() processed_parts.append(lower_part[0].upper() + lower_part[1:] if lower_part else "") return ''.join(processed_parts).strip() def format_pubmed_reference(reference): # 精准匹配PubMed参考文献核心字段 pattern = re.compile( r'^(?P<authors>[^.]+)\.\s*(?P<title>[^.]+)\.\s*(?P<journal>[^.]+)\.\s*(?P<year>\d{4})\s+\w+\s+\d+;(?P<volume>\d+)(\((?P<issue>\d+)\))?:(?P<pages>\d+-\d+)\.' ) match = pattern.search(reference) if not match: return "无效的参考文献格式,请确保符合PubMed标准。" parts = match.groupdict() # 处理作者格式 authors_list = [author.strip() for author in parts['authors'].split(',') if author.strip()] if len(authors_list) > 3: authors_formatted = ', '.join(authors_list[:3]) + ', et al.' elif len(authors_list) == 2: authors_formatted = ' and '.join(authors_list) else: authors_formatted = ', '.join(authors_list) # 处理标题格式 title_formatted = sentence_case(parts['title']) # 拼接最终格式 formatted_reference = ( f"{authors_formatted}. {title_formatted}. {parts['journal']}. {parts['year']};" f"{parts['volume']}" ) if parts.get('issue'): formatted_reference += f"({parts['issue']})" formatted_reference += f":{parts['pages']}." return formatted_reference if __name__ == "__main__": reference_input = input("请输入PubMed参考文献:") formatted_reference = format_pubmed_reference(reference_input) print(formatted_reference)
代码说明
- 正则匹配:重新编写的正则能精准捕获作者、标题、期刊、年份、卷号、期号和页码,自动忽略年份后的月日信息
- 标题转换:专门实现
sentence_case函数,确保标题仅首字母大写,同时保留括号内的专有名词格式 - 作者处理:修正
et al.的标点,优化2位作者的连接逻辑 - 格式合规:严格遵循NLM格式规则,确保各部分标点符号符合要求
内容的提问来源于stack exchange,提问作者Stacey King

