2016-10-02 65 views
3

我正在处理字符串转换问题。要求是这样的:在PARSE中匹配自定义标记

line: {INSERT INTO `pub_company` VALUES ('1', '0', 'ABC大学', 'B', 'admin', '2014-10-09 11:40:44', '', '105210', null)} 

==> 

line: {INSERT INTO `pub_company` VALUES ('1', '0', 'ABC大学', 'B', 'admin', to_date('2014-10-09 11:40:44', 'yyyy-mm-dd hh24:mi:ss'), '', '105210', null)} 

注意:在'2014-10-09 11:40:44'转化为to_date('2014-10-09 11:40:44', 'yyyy-mm-dd hh24:mi:ss')

我的代码看起来像下面:

date: use [digit][ 
    digit: charset "" 
    [4 digit "-" 2 digit "-" 2 digit space 2 digit ":" 2 digit ":" 2 digit] 
] 
parse line [ to date to end] 

,但我得到这个错误:由于date值的位置是

probe parse "SSS 2016-01-01 00:00:00" [thru 3 "S" space date to end] ;true 
probe parse "SSS 2016-01-01 00:00:00" [ to date to end] ; the error above 

** Script error: PARSE - invalid rule or usage of rule: digit 
** Where: parse do either either either -apply- 
** Near: parse line [to date to end] 

我已经做了一些测试,在我的所有数据集中都不一样,我怎样才能达到它并匹配它并做出相应的改变?

回答

3

我做了如下:

line: {INSERT INTO `pub_company` VALUES ('1', '0', 'ABC大学', 'B', 'admin', '2014-10-09 11:40:44', '', '105210', null)} 

d: [2 digit] 
parse/all line [some [p1: {'} 4 digit "-" d "-" d " " d ":" d ":" d {'} p2: (insert p2 ")" insert p1 "to_date(") | skip]] 

>> {INSERT INTO `pub_company` VALUES ('1', '0', 'ABC??', 'B', 'admin', to_date('2014-10-09 11:40:44'), '', '105210', null)} 
3

TO和THRU历史上不允许任意规则作为它们的参数。见#2129

"The syntax of TO and THRU is currently restricted by design, for really significant performance reasons..."

这是relaxed in Red。因此,例如,下面的工作有:

parse "aabbaabbaabbccc" [ 
    thru [ 
     some "a" (prin "a") some "b" (prin "b") some "c" (prin "c") 
    ] 
] 

然而,输出:

abababababc 

这表明它确实不具备的不仅仅是“天真”应用解析规则更好的答案迭代地在每一步。循环PARSE引擎的效率并不像原子性地运行寻找更快方法(例如基本字符串搜索)的TO/THRU。而且括号中代码的重复执行可能与实际意图不符。

尽管如此,它似乎更好。然后,让用户担心他们的代码何时变慢,并在性能问题上调整它。所以很可能Rebol的Ren-C branch将在这方面与Red保持一致,并允许任意规则。

+0

嗨HostileFork,谢谢你的解释。我知道这个的原因。我以间接的方式做到了。 –

2

我已经通过间接的方式进行的:

date: use [digit][ 
    digit: charset "" 
    [4 digit "-" 2 digit "-" 2 digit space 2 digit ":" 2 digit ":" 2 digit] 
] 

line: {INSERT INTO `pub_company` VALUES ('1', '0', 'ABC大学', 'B', 'admin', '2014-10-09 11:40:44', '', '105210', null)} 

parse line [ 
    thru "(" vals: (
     blk: parse/all vals "," 
     foreach val blk [ 
      if parse val [" '" date "'"][ 
       ;probe val 
       replace line val rejoin [ { to_date(} at val 2 {, 'yyyy-mm-dd hh24:mi:ss')}] 
      ] 
     ] 
    ) 
    to end 
    (probe line) 
] 

输出:

{INSERT INTO `pub_company` VALUES ('1', '0', 'ABC大学', 'B', 'admin', to_date('2014-10-09 11:40:44', 'yyyy-mm-dd hh24:mi:ss'), '', '105210', null)} 
2

这里真正的Rebol2解决方案

line: {INSERT INTO `pub_company` VALUES ('1', '0', 'ABC??', 'B', 'admin', '2014-10-09 11:40:44', '', '105210', null)} 
date: use [digit space][ 
    space: " " 
    digit: charset "" 
    [4 digit "-" 2 digit "-" 2 digit space 2 digit ":" 2 digit ":" 2 digit] 
] 

>> parse/all line [ some [ [da: "'" date (insert da "to_date (") 11 skip de: (insert de " 'yyyy-mm-dd hh24:mi:ss'), ") ] | skip ] ] 
== true 
>> probe line 
{INSERT INTO `pub_company` VALUES ('1', '0', 'ABC??', 'B', 'admin', to_date ('2014-10-09 11:40:44', 'yyyy-mm-dd hh24:mi:ss'), '', '105210', null)}