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

Stanford CoreNLP分词规则查询及轻量替代方案咨询

基于UD 2.0规则的轻量正则分词实现(替代Stanford CoreNLP)

Stanford CoreNLP的分词逻辑确实基于UD 2.0分词规范,但官方源码实现冗长且缺乏清晰的规则文档,不管用Stanza、废弃的Python封装还是原生Java版本都很难直接梳理出明确规则。下面针对提出的9项分词要求,给出一套基于正则的轻量实现方案,同时解释特殊token的含义:

核心分词规则与正则实现

以下是针对每项要求的处理逻辑,以及整合后的正则表达式和示例代码:

1. 连字符连接的姓名、复合词不拆分

保留[a-zA-Z]+-[a-zA-Z]+这类结构,将其视为单个token,避免拆分连字符两端的内容。

2. 复数所有格拆分(如boys' → ["boys", "'"])

匹配以复数名词结尾(通常以s结尾)后接单引号的结构,拆分名词和单引号。

3. 单数所有格拆分(如aunt's → ["aunt", "'s"])

匹配非复数名词后接's的结构,拆分名词和's后缀。

4. 尊称缩写不拆分(如Mr./Mrs.保持为单个token)

将Mr\.、Mrs\.、Ms\.、Dr\.这类常见尊称缩写视为整体,不拆分点号和前面的单词。

5. 常规标点独立成token,双连字符不拆分

除了整合到其他结构的标点(如所有格的单引号),其余标点(逗号、句号、问号等)单独作为token;同时保留--为单个token,不拆分为两个-。

6. 缩合动词拆分(如Wouldn't → ["would", "n't"])

匹配以辅音结尾的动词后接n't的缩合结构,拆分为动词原型和n't。

7. and/or不拆分

将and/or视为单个固定token。

8. 人称代词缩写拆分(如I'm → ["I", "'m"])

匹配人称代词后接'm/'re/'ve等缩写后缀的结构,拆分代词和后缀。


整合后的正则分词逻辑

可以通过优先匹配需要保留的整体结构,再处理拆分规则的顺序来实现,示例Python代码如下:

import re

def core_nlp_style_tokenize(text):
    # 定义需要优先保留为单个token的结构
    preserve_patterns = [
        r'(Mr\.|Mrs\.|Ms\.|Dr\.)',  # 尊称缩写
        r'and/or',                  # 固定搭配
        r'[a-zA-Z]+-[a-zA-Z]+',     # 连字符连接的姓名/复合词
        r'--'                       # 双连字符
    ]
    # 定义拆分规则(按优先级排序)
    split_patterns = [
        r"([a-zA-Z]+)'$",           # 复数所有格拆分(如boys' → boys + ')
        r"([a-zA-Z]+)'s",           # 单数所有格拆分(如aunt's → aunt + 's)
        r"([a-zA-Z]+)n't",          # 缩合动词拆分(如Wouldn't → would + n't)
        r"([I|You|He|She|It|We|They])'m",  # 人称代词缩写拆分(如I'm → I + 'm)
        r"([I|You|He|She|It|We|They])'re",
        r"([I|You|He|She|It|We|They])'ve",
        r"([I|You|He|She|It|We|They])'ll",
        r'([^\w\s\-])',             # 常规标点拆分(除了连字符)
    ]
    
    # 先替换需要保留的结构为临时标记,避免被拆分
    temp_markers = []
    for idx, pattern in enumerate(preserve_patterns):
        def replace_func(match, idx=idx):
            temp_markers.append(match.group(0))
            return f'__TEMP{idx}__'
        text = re.sub(pattern, replace_func, text)
    
    # 应用拆分规则
    for pattern in split_patterns:
        if r'\2' in pattern:
            text = re.sub(pattern, r'\1 \2', text)
        else:
            text = re.sub(pattern, r'\1 ', text)
    
    # 还原临时标记的内容
    for idx, marker in enumerate(temp_markers):
        text = text.replace(f'__TEMP{idx}__', marker)
    
    # 分割并过滤空字符串
    tokens = [token.strip() for token in text.split() if token.strip()]
    return tokens

# 测试示例
test_cases = [
    "Marie Illonig-Alberts is a well-intentioned person",
    "The boys' toys are next to aunt's chair",
    "Mr. Smith and Mrs. Jones went to the store",
    "This is a test--does it work?",
    "Wouldn't you like to know I'm here?",
    "We can choose and/or modify the plan"
]
for case in test_cases:
    print(f"输入: {case}")
    print(f"分词结果: {core_nlp_style_tokenize(case)}\n")

特殊token -LRB-/-RRB-说明

在Stanford CoreNLP的输出中,-LRB-和-RRB-是左括号(和右括号)的标准化标记。CoreNLP会将原始文本中的括号替换为这两个特殊token,目的是:

  1. 统一处理不同格式的括号(如全角/半角括号);
  2. 避免括号作为标点符号被误拆分或干扰后续的句法分析;
  3. 符合UD标注规范中对括号的标准化表示。
    其他类似的特殊token还有-LCB-(左大括号{)、-RCB-(右大括号})、-LSB-(左方括号[)、-RSB-(右方括号])。

内容的提问来源于stack exchange,提问作者lrthistlethwaite

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 05:47:39