2016-10-02 3 views
3

Je travaille sur un problème de transformation de cordes. L'exigence est comme ceci:Correspondre le jeton autodéfini dans 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)} 

Remarque: le '2014-10-09 11:40:44' est transformé en to_date('2014-10-09 11:40:44', 'yyyy-mm-dd hh24:mi:ss').

Mon code ressemble ci-dessous:

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

mais j'eu cette erreur:

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

J'ai fait quelques 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 

Comme la position de date valeur est pas la même chose dans tout mon ensemble de données, comment puis-je l'atteindre et le faire correspondre et faire le changement correspondant?

Répondre

3

Je l'ai fait comme ci-dessous:

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

Depuis toujours, TO et THRU ne permettent pas de règles arbitraires en tant que paramètres. Voir #2129:

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

Ce fut relaxed in Red. Ainsi, par exemple, ce qui suit travailler là-bas:

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

Cependant, il émet:

abababababc 

Cela montre qu'il n'a vraiment pas de meilleure réponse que juste « naïvement » application de la règle d'analyse syntaxique itérativement à chaque étape. La mise en boucle du moteur PARSE n'est pas aussi efficace que l'exécution atomique d'un TO/THRU pour lequel il existe des méthodes de recherche plus rapides (recherche de chaîne de base, par exemple). Et l'exécution répétée du code entre parenthèses peut ne pas correspondre à ce qui était réellement prévu.

Encore ... il semble préférable de le permettre. Ensuite, laissez les utilisateurs s'inquiéter de la lenteur de leur code et des performances si cela est important. Il y a donc fort à parier que le Ren-C branch de Rebol s'alignera sur Red à cet égard, et autorisera des règles arbitraires.

+0

Salut HostileFork, merci pour votre explication. Je connais la raison de ceci. Je l'ai fait indirectement. –

2

Je l'ai fait par une voie indirecte:

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

La sortie:

{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

Voici une vraie solution 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)}