3

I am working on a string-transforming problem. The requirement is like this:

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)}

Note: the '2014-10-09 11:40:44' is transformed to to_date('2014-10-09 11:40:44', 'yyyy-mm-dd hh24:mi:ss').

My code looks like below:

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

but I got this error:

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

I have made some tests:

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

As the position of date value is not the same in all my data set, how can I reach it and match it and make the corresponding change?

Wayne Cui
  • 835
  • 7
  • 15

4 Answers4

3

TO and THRU have historically not allowed arbitrary rules as their parameters. See #2129:

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

This was relaxed in Red. So for example, the following will work there:

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

However, it outputs:

abababababc

This shows that it really doesn't have a better answer than just "naively" applying the parse rule iteratively at each step. Looping the PARSE engine is not as efficient as atomically running a TO/THRU for which faster methods of seeking exist (basic string searches, for instance). And the repeated execution of code in parentheses may not line up with what was actually intended.

Still...it seems better to allow it. Then let users worry about when their code is slow and performance tune it if it matters. So odds are that the Ren-C branch of Rebol will align with Red in this respect, and allow arbitrary rules.

  • Hi HostileFork, thanks for your explanation. I know the reason for this. I have made it by an indirect way. – Wayne Cui Oct 02 '16 at 11:50
3

I did as below:

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)}
endo64
  • 2,269
  • 2
  • 27
  • 34
2

I have made it by an indirect way:

date: use [digit][
    digit: charset "0123456789"
    [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)
]

The output:

{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)}
Wayne Cui
  • 835
  • 7
  • 15
2

Here a true Rebol2 solution

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 "0123456789"
     [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)}
sqlab
  • 6,412
  • 1
  • 14
  • 29