You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在ANTLR中获取纯文本而非令牌的实现方法

获取ANTLR解析器中的纯文本内容

首先得提个小细节:你语法里的tag1Ops用了END_2_TAG,这大概率是笔误吧?应该对应END_1_TAG才对,不然标签开闭不匹配,解析肯定会出问题,先把这个小坑填上。

接下来回到你的核心需求:获取纯文本而非零散令牌。这里有两种实用方案,看你更倾向哪种:

方式一:优化语法,用词法规则捕获完整文本块

这种方式最高效,能让ANTLR直接把连续文本当成一个令牌,不用后续拼接。

调整后的语法如下:

grammar YourGrammar;

code : codeBlock* EOF;
codeBlock : text | tag1Ops | tag2Ops ;
// 修正tag1Ops的结束标签,匹配对应的END_1_TAG
tag1Ops: START_1_TAG ID END_1_TAG ;
tag2Ops: START_2_TAG ID END_2_TAG ;
// 解析器规则直接引用TEXT词法令牌
text: TEXT;

// 注意:把HTML转义的&lt;换成实际的<,ANTLR语法里直接写原始字符即可
START_1_TAG : '<%' ;
END_1_TAG : '%>' ;
START_2_TAG : '<<';
END_2_TAG : '>>' ;
ID : [A-Za-z_][A-Za-z0-9_]*;
INT_NUMBER: [0-9]+;
// 隐藏无关空白(如果需要保留文本内的空格,可删掉这条规则)
WS : ( ' ' | '\n' | '\r' | '\t')+ -> channel(HIDDEN);
// 核心:定义TEXT词法规则,匹配所有非起始标签的内容
// 逻辑:要么是不含<的字符,要么是<后不跟%或<的内容(避免误匹配起始标签)
TEXT: (~('<') | '<' (~('%' | '<')))+;

// 删掉多余的ANY_CHAR和SPACES,TEXT已经覆盖这些场景,留着会干扰规则匹配

然后在代码中(以Java为例),用ANTLR的监听器或访问器提取文本:

监听器实现示例:

public class YourTextListener extends YourGrammarBaseListener {
    @Override
    public void enterText(YourGrammarParser.TextContext ctx) {
        // 直接获取TEXT令牌的完整文本
        String plainText = ctx.TEXT().getText();
        // 这里可以做自定义处理,比如打印、存储等
        System.out.println("提取到纯文本:" + plainText);
    }
}

访问器实现示例:

public class YourTextVisitor extends YourGrammarBaseVisitor<String> {
    @Override
    public String visitText(YourGrammarParser.TextContext ctx) {
        return ctx.TEXT().getText();
    }
}

方式二:不修改语法,拼接令牌文本(适合临时场景)

如果不想改动现有语法,也可以遍历text节点下的所有令牌,拼接出完整文本:

@Override
public void enterText(YourGrammarParser.TextContext ctx) {
    StringBuilder textBuilder = new StringBuilder();
    // 遍历text节点下的所有令牌并拼接
    for (Token token : ctx.getTokens()) {
        textBuilder.append(token.getText());
    }
    String plainText = textBuilder.toString();
    // 执行后续处理
}

不过这种方式效率稍低,因为需要拼接多个零散令牌,更推荐第一种方案。

最后提醒:词法规则的顺序很关键!一定要把TEXT放在所有其他词法规则的后面,这样ANTLR会优先匹配标签、ID、数字等特定令牌,剩下的内容才会被TEXT捕获,避免标签被误识别为文本。

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

火山引擎 最新活动