使用jFlex标记时间戳并处理ISO格式

时间:2015-07-18 00:40:09

标签: java tokenize jflex

我正在尝试使用各种日期格式解决日期标记化问题,其中一个可能采用ISO8601格式,使用“T”作为分隔符。我希望能够知道字符'T'是一个时间戳,当它有一个数字在它之前和之后。

例如,如果我有一个数组

String[] timestamp = {"Time: 12/45/60", "2015-07-13T05:30:59"}

我想要

的分割结果
(Time) (:) (12) (/) (45) (/) (60) 
(2015) (-) (07) (-) (13) (T) (05) (:) (30) (:) (59)

我正在使用jFlex来制作标记器,我这样编写了我的.flex文件:

    %%
    %class Lexer
    SpecialT = (\dT\d)
    Parameter = [:jletterdigit:]+
    Delimiter = [^A-Za-z0-9]|{SpecialT}
    %%
    [:digit:]+ {return new Datetoken(yytext(), "Int");}
    {Delimiter} {return new Datetoken(yytext(), "Delimiter");}
    {Parameter} {return new Datetoken(yytext(), "Text");}

但是,此标记化程序仅解析符号,但不解析“T”。有人有什么建议吗?非常感谢你。

1 个答案:

答案 0 :(得分:0)

它适用于我,或者更确切地说它适用于语法描述的东西。

<!-- language: lang-none -->
7-29T08:42
[Int] 7
[Delimiter] -
[Text] 29T08
[Delimiter] :
[Int] 42
[Delimiter] 

确实,扫描仪与-分隔符匹配后

  • 得到2,匹配[:digit:] +和{Parameter}
  • 得到9,匹配[:digit:] +和{Parameter}
  • 得到T,与[:digit:] +不匹配但仍匹配{参数}
  • 然后08保持匹配{参数}
  • :与{Parameter}不匹配;并返回令牌{Parameter} 29T08

请注意,如果仅输入以下内容,则会识别{SpecialT}:

<!-- language: lang-none -->
5T6
[Delimiter] 5T6

你的第一个问题是SpecialT捕获太多了。

你的第二个问题是{Parameter}几乎与所有内容相匹配。

我建议您更准确地定义ISO日期:

// HH:MM or HH:MM:ss
IsoTime = {Dig2} {Delimiter} {Dig2} ({Delimiter} {Dig2})?

// yyyy-mm-dd or yyyy-mm-ddT<isotime>
IsoDate =  {Dig4} ({Delimiter} {Dig2}){2} (T {IsoTime})?

这将创建一个完整的2015-07-29T16:42的好令牌。