在Overleaf中搜索缩略词的正则表达式方法
Overleaf支持正则表达式搜索,可用来查找文档中的缩略词,以帮助构建缩略词表。
基本操作
- Ctrl+F 打开搜索
- 点击 .* 启用正则搜索
- 输入:
[A-Z]{2,}
常用正则表达式
[A-Z]{2,}
: 匹配2个及以上连续大写字母[A-Z]{2}
: 严格匹配2个大写字母\b[A-Z]{2,}\b
: 匹配词边界的大写字母序列
局限性
- 无法匹配包含数字的缩略词
- 可能误匹配非缩略词的大写序列 (如\cite{}中的大写序列)
最终解决方案
- 直接使用python读取tex,然后自定义逻辑提取缩略词,并且输出IEEE格式的缩略词表
import re
def read_tex_file(tex_path):
"""
读取 tex 文件所有内容
"""
try:
with open(tex_path, 'r', encoding='utf-8') as f:
text = f.read()
return text
except Exception as e:
raise IOError(f"无法读取 tex 文件: {e}")
def remove_citations(text):
"""
移除 \cite 命令,防止该部分出现连续大写字母影响缩略词识别
同时考虑可选参数的情况,例如 \cite[...]{...}
"""
pattern = r'\\cite(?:\[[^\]]*\])?\{[^}]*\}'
return re.sub(pattern, '', text)
def remove_references(text):
"""
移除参考文献部分:
1. 删除 thebibliography 环境中的内容;
2. 如果存在“参考文献”或“REFERENCES”等关键字,其后的内容不再分析。
"""
text = re.sub(r'\\begin\{thebibliography\}.*?\\end\{thebibliography\}', '', text, flags=re.DOTALL)
ref_markers = ["参考文献", "REFERENCES"]
idx = len(text)
for marker in ref_markers:
pos = text.find(marker)
if pos != -1 and pos < idx:
idx = pos
return text[:idx]
def remove_existing_acronym_table(text):
"""
移除已有的 IEEE 缩略词表,避免重复识别
"""
pattern = r'\\begin\{IEEEdescription\}.*?\\end\{IEEEdescription\}'
return re.sub(pattern, '', text, flags=re.DOTALL)
def extract_acronym_definitions(text):
"""
利用正则表达式匹配形如 "Full term (ACRONYM)" 的缩略词定义,
返回字典,key 为缩略词,value 为全称。
这里先匹配较宽松的形式,再在代码中对缩略词进行验证:
- 缩略词必须长度≥2,
- 不能全部为数字,
- 必须至少包含两个大写字母(例如 "AoA" 满足要求,而 "Real" 不满足)。
"""
# 这里的全称部分允许出现字母、空格、连字符、& 符号以及 LaTeX 的反斜杠命令
pattern = re.compile(r'(?P<full>[A-Za-z\\][A-Za-z \-\&\\]+?)\s*\((?P<abbr>[A-Za-z0-9]{2,})\)')
mappings = {}
for match in pattern.finditer(text):
abbr = match.group("abbr").strip()
# 过滤:如果缩略词全部为数字或大写字母数量不够,则跳过
if abbr.isdigit():
continue
if sum(1 for c in abbr if c.isupper()) < 2:
continue
full = match.group("full").strip()
if abbr not in mappings:
mappings[abbr] = full
return mappings
def find_candidate_acronyms(text, freq_threshold=2):
"""
利用正则表达式匹配所有由字母和数字组成、长度≥2的单词,
然后在 Python 中检查:
- 排除全为数字的单词;
- 要求该单词中至少包含两个大写字母。
对所有符合条件的候选词统计出现频次,并过滤掉出现次数不足 freq_threshold 的项;
最后与通过定义匹配到的缩略词取并集,确保在定义处出现的缩略词(即使频次较低)也被保留。
"""
pattern = r'\b[A-Za-z0-9]{2,}\b'
candidates = re.findall(pattern, text)
freq = {}
for candidate in candidates:
# 排除纯数字
if candidate.isdigit():
continue
# 检查至少包含两个大写字母
if sum(1 for c in candidate if c.isupper()) < 2:
continue
freq[candidate] = freq.get(candidate, 0) + 1
filtered = {abbr for abbr, count in freq.items() if count >= freq_threshold}
defined = set(extract_acronym_definitions(text).keys())
all_acronyms = filtered.union(defined)
return sorted(all_acronyms)
def generate_ieee_acronym_table(acronyms, definitions):
"""
根据缩略词列表及其对应全称生成 IEEE 格式的缩略词表,格式例如:
\begin{IEEEdescription}[\IEEEsetlabelwidth{$MMMM$}\IEEEusemathlabelsep]
\item[AI] Artificial Intelligence
...
\end{IEEEdescription}
若某缩略词没有对应全称,则标记为 “未定义”。
Label 宽度利用最长缩略词的长度生成占位字符串(用字母 M 模拟)。
"""
if acronyms:
max_len = max(len(a) for a in acronyms)
else:
max_len = 2
placeholder = "$" + "M" * max_len + "$"
latex_lines = []
latex_lines.append(r"\begin{IEEEdescription}[\IEEEsetlabelwidth{" + placeholder + r"}\IEEEusemathlabelsep]")
for abbr in acronyms:
expansion = definitions.get(abbr, "").strip()
if not expansion:
expansion = "未定义"
latex_lines.append(r"\item[" + abbr + r"] " + expansion)
latex_lines.append(r"\end{IEEEdescription}")
return "\n".join(latex_lines)
def main():
tex_path = input("请输入 tex 文件的路径: ").strip()
try:
raw_text = read_tex_file(tex_path)
except Exception as e:
print("读取 tex 文件失败,请检查文件路径与权限。")
print("错误信息:", e)
return
# 预处理步骤:移除 \cite 命令、参考文献部分和已有的缩略词表
text_no_cites = remove_citations(raw_text)
text_no_refs = remove_references(text_no_cites)
clean_text = remove_existing_acronym_table(text_no_refs)
# 提取定义以及候选的缩略词
acronym_definitions = extract_acronym_definitions(clean_text)
acronym_candidates = find_candidate_acronyms(clean_text, freq_threshold=1)
if not acronym_candidates:
print("未检测到可能的缩略词。")
return
ieee_table = generate_ieee_acronym_table(acronym_candidates, acronym_definitions)
print("\n生成的 IEEE 格式缩略词表:\n")
print(ieee_table)
if __name__ == "__main__":
main()