如何在ANTLR4中忽略行首任意文本,仅匹配行尾的factor、value语法规则
问题根源
你的原有语法未限定factor% value必须出现在行尾位置,ANTLR默认会匹配第一个符合规则的INT作为factor,因此会错误捕获行中前置的数字。
解决方案
方案1:纯ANTLR语法实现(用语义谓词限定匹配规则)
通过语义谓词限制,只有当INT后紧跟%、FLOAT、换行符序列时,才会被识别为factor,其余场景下的数字、百分号都会被归入普通文本sometext,完整语法示例如下:
grammar InvoiceParse; line: sometext factor '%' value NEWLINE; // 匹配所有非换行字符,直到命中尾部的factor% value结构 sometext: ( ANY_CHAR )* ; // 语义谓词:仅当INT后是%、FLOAT、换行时,才被识别为factor factor: INT { _input.LT(2).getType() == PERCENT && _input.LT(3).getType() == FLOAT && _input.LT(4).getType() == NEWLINE }? ; value: FLOAT; // 词法规则(顺序优先匹配更具体的token) INT: [0-9]+; FLOAT: [0-9]+ '.' [0-9]+; PERCENT: '%'; NEWLINE: '\r'? '\n'; // 兜底匹配所有单个非换行字符 ANY_CHAR: ~[\r\n];
方案2:更适配OCR场景的轻量方案
OCR识别的发票内容往往存在格式波动、识别误差,纯语法规则刚性太强容易匹配失败,推荐分两步处理:
- 先通过ANTLR简单匹配整行文本,不做细拆分
- 对拿到的单行字符串,用正则从行尾反向提取目标字段:正则
(\d+)% +(\d+\.\d+)\s*$可以匹配行末的factor和value,剩余的前缀内容就是sometext。
内容的提问来源于stack exchange,提问作者Bernhard
相关产品推荐
相关产品推荐

