当前位置: 首页 > 知识库问答 >
问题:

用转义字符解析带引号的字符串

鞠隐水
2023-03-14

我在解析antlr4中的格式行列表时遇到了一个问题

* this is a string
*  "first"  this is "quoted"
* this is "quoted with \" "
(list 
(line * (value (string this is a string))) 
(line * (value (parameter first) (string   this is) (parameter quoted))) 
(line * (value (string this is) (parameter quoted with " )))
)
grammar List;
list : line+;
line : '*' (WS)+ value* NEWLINE;
value : string
      | parameter
      ;
string : ((WORD) (WS)*)+;
parameter : '"'((WORD) (WS)*)+ '"';
WORD : (~'\n')+;
WS : '\t' | ' ';
NEWLINE     : '\n';

但这是失败的第一个字符识别'*'本身,这使我困惑。

第1行:0不匹配的输入'*这是一个字符串',应为'*'

共有1个答案

白宏放
2023-03-14

问题是你的lexer太贪婪了。规则

WORD : (~'\n')+;

几乎匹配所有东西。这将导致lexer为您的输入生成以下标记:

  • 标记1:单词(*这是一个字符串)
  • 标记2:换行符
  • 标记3:单词(`*“first”这是“quoteded”)
  • 标记4:换行符
  • 标记5:单词(*这是“用引号\”“)

是的,这是正确的:只有单词换行标记。ANTLR的lexer试图用尽可能多的字符构造令牌,但它不会“监听”解析器试图匹配的字符。

错误消息:

第1行:0不匹配的输入'*这是一个字符串',应为'*'

告诉您:在第1行,索引0中遇到了带有文本'*这是一个字符串'(类型word)的标记,但解析器试图匹配该标记:'*'

尝试如下所示:

grammar List;

parse
 : NEWLINE* list* NEWLINE* EOF
 ;

list
 : item (NEWLINE item)*
 ;

item
 : '*' (STRING | WORD)* 
 ;

BULLET : '*';
STRING : '"' (~[\\"] | '\\' [\\"])* '"';
WORD : ~[ \t\r\n"*]+;
NEWLINE : '\r'? '\n' | '\r';
SPACE : [ \t]+ -> skip;

它按以下方式解析示例输入:

(parse 
  (list 
    (item 
      * this is a string) \n 
    (item 
      * "first" this is "quoted") \n 
    (item 
      * this is "quoted with \" ")) 
   \n 
  <EOF>)
 类似资料:
  • 问题内容: 我知道可以在Java字符串中用双引号将符号放在双引号之前。但是,如果在字符串中经常使用双引号,那么是否有一种方法可以将字符串标记一次,因此不需要在每个双引号之前写上符号吗?(就像在C#中一样,可以将符号放在字符串之前)示例: 代替 问题答案: 你不能 但是,如果您懒得不能使用双引号,则可以使用一些技巧。例如: 输出:

  • 问题内容: 如何获得以下两个文本中引号之间的含义? 我的问题是,如果引号被转义,则应将其忽略,但是有可能使反斜杠转义。 我想获得以下团体。 问题答案: 匹配带引号的字符串,包括其中出现的所有转义字符。 说明:

  • 问题内容: 我的字符串中有双引号,因为我会这样做: 我将如何用Java做到这一点? 问题答案: 否。此类功能在Java中不可用。 从Sun 文档: 当在打印语句中遇到转义序列时,编译器将对其进行相应的解释。例如,如果要将引号放在引号内,则必须在内部引号上使用转义序列\“。要打印句子 你会写

  • 我使用此模式在解析器中匹配单引号字符串: 但是我需要正则表达式,它可以找到带有 postgres 的单引号字符串,例如 bied of single qoutes(加倍单个 qoutes)。需要匹配这样的东西: 我想为以单引号开头和结尾的字符串找到最短的匹配项,因此上面的字符串意味着 3 个子字符串:

  • 我可以将替换为其他一些字符序列(例如)来执行字符串替换,但是如果我可以用正则表达式来替换,这将更加清楚。

  • 问题内容: 我想用定界符空格分割字符串。但它应该智能地处理带引号的字符串。例如,像这样的字符串 它应该返回三个字符串John Smith,Ted和Barry。 问题答案: 弄乱它之后,您可以使用Regex来实现。在以下位置运行“全部匹配”的等效项: 一个Java示例: 输出: 上面使用示例的正则表达式分解可以在这里查看: http://regex101.com/r/wM6yT9 综上所述,正则表达