scala通过尾递归解析提取字段信息

 

一、背景

获取数据中以“|”作为字段间的分隔符,但个别字段中数据也是以“|”作为分隔符。因此,在字段提取时需要保护数据完整性。

 

二、实现

1.数据以“|”分隔,可以采用递归方式迭代解析。通过尾递归方式降低运行风险;

2.尾递归中使用模式匹配;

3.解析时,根据separator做遍历,“‘”和“’”(一对引号之间的数据作为一个整体cell),引号前数据位head(即使为空,也可以),cell后的数据由下一次迭代解析,则整个结构为:result+head+cell(引号间的数据)+(head+cell+(head+cell+(...)))

4.默认数据中引号成对出现;

5.具体实现如下:

 1 val input="123||abc||lat|||'120.15|34.56'||lon||'112.135|30.124'|location|grid|'101|26|37'|0755|x|"
 2 
 3 def separator(str:String,sep:String,result:Array[String]):Array[String]={str.indexOf(sep) match{
 4   case v if v<0 =>result++str.split("\\|",-1)
 5   case x  =>{
 6     val head=str.substring(0,x).stripSuffix("|").split("\\|",-1)
 7     val next=str.substring(x+1).indexOf(sep)
 8     val cell=Array(str.substring(x+1,x+next+1).replaceAll("\\|",","))
 9     separator(str.substring(x+next+3),sep,result++head++cell)}
10 }}
11 
12 println(separator(input,"'",Array()).toList)

 

三、总结

1.使用尾递归时,要保证每次迭代要有结果作为下次迭代的输入;

2.substring提取子字符串时为前闭后开;

3.字符串做split时尽量使用index=-1,保证||之间为一个空的数据,但不能丢弃;

4.replaceAll替换字符时,注意".$|()[{^?*+\\"需要做转译;

5.保证|‘不会产生多余空元素,需要对head的字符串做stripSuffix去除动作。

 

posted on 2017-08-30 16:33  sayhihi  阅读(445)  评论(0编辑  收藏  举报