小编Nic*_* B.的帖子

从任意纯文本扩展特定标签

我想解析纯文本注释并在其中查找某些标签。我要寻找的标签类型如下:

<name#1234>
Run Code Online (Sandbox Code Playgroud)

其中“名称”是[az]字符串(来自固定列表),“ 1234”表示[0-9] +数字。这些标签可以出现在字符串中零次或多次,并被任意其他文本包围。例如,以下字符串均有效:

"Hello <foo#56> world!"
"<bar#1>!"
"1 &lt; 2"
"+<baz#99>+<squid#0> and also<baz#99>.\n\nBy the way, maybe <foo#9876>"
Run Code Online (Sandbox Code Playgroud)

以下字符串均无效:

"1 < 2"
"<foo>"
"<bar#>"
"Hello <notinfixedlist#1234>"
Run Code Online (Sandbox Code Playgroud)

最后一个无效,因为“ notinfixedlist”不是受支持的命名标识符。

我可以使用简单的正则表达式轻松地对此进行解析(例如,为简单起见,我省略了命名组):

<[a-z]+#\d+>
Run Code Online (Sandbox Code Playgroud)

或直接指定一个固定列表:

<(foo|bar|baz|squid)#\d+>
Run Code Online (Sandbox Code Playgroud)

但出于某些原因,我想使用antlr:

  • 我希望任何与该格式不匹配的内容都导致解析错误,因此,如果文本包含“ <”或“>”但与模式不匹配,则它将失败。这些字符必须转义为“&lt;”。和“&gt;” 如果不是标签则分别添加。
  • 将来我可能会扩展它以支持其他类型的模式(例如:“ {foo + 666}”或“ [[@ 1234]]”,并希望避免正则表达式语句激增。只有一个语法文件,我可以扩展会很棒。
  • 我喜欢antlr4实现访客模式,并且遇到特定类型的标记时调用我的代码的事实,而不必同时修改各种正则表达式。

如何使用antlr4实施这样的语法?我看到的大多数示例都是针对遵循完整文本严格规则的语言的,而我只希望语法适用于任意文本内的匹配模式。

我想出了这个,我认为是正确的:

grammar Tags;

parse 
    : ( tag | text )*
    ;

tag 
    : '<' fixedlist '#' ID '>'
    ;

fixedlist 
    : 'foo' 
    | 'bar' 
    | 'baz' 
    | 'squid';

text 
    : ~('<' | '>')+
    ;

ID …
Run Code Online (Sandbox Code Playgroud)

c# regex parsing text-parsing antlr4

5
推荐指数
1
解决办法
131
查看次数

标签 统计

antlr4 ×1

c# ×1

parsing ×1

regex ×1

text-parsing ×1