You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:47:21