基于tidytext/tm/quanteda的瑞士法律引用正则匹配需求
我来帮你搞定瑞士法律引用的文本挖掘任务,核心是写出符合需求的正则表达式,然后完成筛选和统计操作。
第一步:理解需求与正则设计
你的文本已经做了tolower和removePunctuation处理,所以所有内容都是小写无标点的。我们需要的正则要满足:
- 匹配单个瑞士法律条款(Art.1-67),中间可以包含合法层级(abs x、lit x、satz x)
- 最终指向指定法典(比如MedBG)
- 排除包含多个条款、无关内容或其他法典的引用
针对处理后的文本,我设计了这个正则:
# 匹配MedBG的Art.1-67,支持中间合法层级 regex_medbg <- "\\bart (?:[1-9]|[1-5]\\d|6[0-7])(?:\\s+(abs\\s+\\d+|lit\\s+[a-z]|satz\\s+\\d+))*\\s+medbg\\b"
正则解释:
\\b:单词边界,避免匹配类似art123或medbgxyz的无效内容art:匹配处理后的条款前缀(原Art.变成art)(?:[1-9]|[1-5]\\d|6[0-7]):匹配1-67的数字(非捕获组)(?:\\s+(abs\\s+\\d+|lit\\s+[a-z]|satz\\s+\\d+))*:零个或多个合法层级(abs+数字、lit+小写字母、satz+数字),非捕获组\\s+medbg:匹配法典名称
用你的测试集验证(先处理成小写无标点):
lawCitation_processed <- c("art 1 medbg","art 42 abs 2 und 100 abs 1 medbg","art 1 abs 1 lit a medbg","art 36 abs 1 lit b medbg","art 1 satz 2 bgg und abs 1 lit a lit b","art 22 totally random number 21 medbg") grepl(regex_medbg, lawCitation_processed) # 返回:TRUE FALSE TRUE TRUE FALSE FALSE
如果只想匹配Art.1,把正则中的数字部分换成1即可:
regex_art1_medbg <- "\\bart 1(?:\\s+(abs\\s+\\d+|lit\\s+[a-z]|satz\\s+\\d+))*\\s+medbg\\b" grepl(regex_art1_medbg, lawCitation_processed) # 返回:TRUE FALSE TRUE FALSE FALSE FALSE(完全符合你的预期)
第二步:筛选含指定引用的文档
用dplyr::filter结合正则筛选文档:
library(dplyr) # 筛选包含MedBG合法引用的文档 filtered_docs <- docs_tidy %>% filter(grepl(regex_medbg, text))
第三步:统计每个文档的引用次数
我们可以用stringr::str_extract_all提取所有匹配的引用,再分组统计:
统计具体引用的次数(含层级)
library(stringr) library(tidyr) citation_details <- filtered_docs %>% # 提取每个文档中所有匹配的引用 mutate(citation_matches = str_extract_all(text, regex_medbg)) %>% # 展开成每行一个引用 unnest(citation_matches) %>% # 按文档id和引用内容分组统计次数 group_by(id, citation_matches) %>% summarise(citation_count = n(), .groups = "drop") %>% # 按文档和次数排序 arrange(id, desc(citation_count))
按条款聚合统计(忽略中间层级)
如果想把同一条款的不同层级引用合并统计(比如art 1 medbg和art 1 abs 1 lit a medbg都算Art.1的引用):
citation_by_article <- citation_details %>% # 提取条款号 mutate(article_number = str_extract(citation_matches, "(?<=art )\\d+")) %>% # 按文档和条款号分组统计总次数 group_by(id, article_number) %>% summarise(total_citations = sum(citation_count), .groups = "drop") %>% arrange(id, desc(total_citations))
可选:处理带标点的文本
如果你的预处理没有完全去掉标点(比如保留了.),可以用这个兼容版本的正则:
regex_medbg_with_punct <- "\\bart\\.?\\s+(?:[1-9]|[1-5]\\d|6[0-7])(?:\\s+abs\\.?\\s+\\d+|\\s+lit\\.?\\s+[a-z]|\\s+satz\\s+\\d+)*\\s+medbg\\b"
内容的提问来源于stack exchange,提问作者captcoma
相关产品推荐
相关产品推荐

