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

如何在PLY中配置默认TEXT Token以捕获非匹配内容?

PLY Lex 实现TEXT与多信号Token的正确分词

你的问题核心是PLY的lexer匹配规则导致TEXT吃掉了全部内容——[\s\S]+是贪婪匹配,会优先匹配最长的字符串,直接覆盖了后面的信号规则。这里给你一个简洁的方案,不用写复杂正则,还能轻松扩展十多种信号:

解决方案代码

import ply.lex as lex
import re

# 把所有信号按「Token名称: 匹配字符串」的格式存字典,新增信号直接加这里
signals = {
    'SIGNAL1': 'HELP!',
    'SIGNAL2': 'OVER HERE!'
}

# 生成Token列表:先TEXT,再所有信号
tokens = ['TEXT'] + list(signals.keys())

# 动态生成TEXT的正则:匹配任意字符,直到遇到任意一个信号(非贪婪模式)
escaped_signals = [re.escape(signal_str) for signal_str in signals.values()]
t_TEXT = r'(?:(?!' + '|'.join(escaped_signals) + r').)+'

# 动态绑定每个信号的Token规则(自动转义特殊字符,避免正则冲突)
for token_name, signal_str in signals.items():
    globals()[f't_{token_name}'] = re.escape(signal_str)

# 测试示例
data = "some random text HELP! lorem ipsum OVER HERE! more end text"
lexer = lex.lex()
lexer.input(data)
while True:
    tok = lexer.token()
    if not tok:
        break
    print(f'({tok.type}, "{tok.value}")')

代码说明

  1. 信号管理:把所有信号放进字典,新增信号只需要在字典里加键值对,不用改其他逻辑,适合你十多种信号的场景。
  2. TEXT正则生成:用(?!信号)的负向前瞻语法,让TEXT只匹配「不会触发任何信号的连续字符」,自动停在信号前,避免贪婪吃掉全部内容。
  3. 自动转义:用re.escape()处理信号字符串,比如HELP!里的!是正则特殊字符,转义后不会引发匹配错误。

执行结果

运行后会输出:

(TEXT, "some random text ")
(SIGNAL1, "HELP!")
(TEXT, " lorem ipsum ")
(SIGNAL2, "OVER HERE!")
(TEXT, " more end text")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 12:30:42