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

使用PLY处理带转义换行的单行注释时的匹配错误问题

问题原因

你遇到的问题核心是正则分支的匹配优先级问题:

  • 你原来使用的正则 r'.|\\\n' 会优先匹配左侧的单个任意字符(.),当遇到反斜杠\时,会先匹配单个\作为普通注释内容,剩下的换行符\n就会触发COMMENT状态的结束规则,导致换行后的内容直接回到初始状态被解析为普通token。
  • 普通换行的结束规则本身没有问题,问题是转义换行的组合\\\n没有被优先匹配,提前吃掉反斜杠加换行的两个字符。
修复方案

调整COMMENT状态的规则顺序,把转义换行的匹配放在最高优先级,单独作为规则实现,确保转义换行不会被拆分匹配:

  1. 优先匹配转义换行\\\n,匹配到直接丢弃,保持在COMMENT状态
  2. 匹配所有非换行的注释内容,直接丢弃
  3. 最后匹配普通换行,结束注释切回初始状态
修改后示例代码
import ply.lex as lex

states = (
    ('COMMENT', 'exclusive'),
)
# 按需添加你需要的其他token
tokens = ('NUMBER',)

# 初始状态匹配# 进入注释状态
def t_begin_COMMENT(t):
    r'\#'
    t.lexer.begin('COMMENT')

# 最高优先级:匹配转义换行,直接丢弃
def t_COMMENT_escaped_newline(t):
    r'\\\n'
    pass

# 匹配所有非换行的注释内容,直接丢弃
def t_COMMENT_content(t):
    r'[^\n]'
    pass

# 匹配普通换行,结束注释
def t_COMMENT_end(t):
    r'\n'
    t.lexer.begin('INITIAL')

def t_COMMENT_error(t):
    t.lexer.skip(1)

# 示例数字token规则
def t_NUMBER(t):
    r'\d+'
    t.value = int(t.value)
    return t

# 初始状态忽略空格
t_ignore = ' \t'

def t_error(t):
    t.lexer.skip(1)

# 测试
lexer = lex.lex()
string = "# test \\\ns \n4"
lexer.input(string)
for tok in lexer:
    print(tok)

运行上述代码只会输出NUMBER: 4,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 04:24:05