匹配 PARSE 中自定义的 token
Match self-define token in 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 "0123456789"
[4 digit "-" 2 digit "-" 2 digit space 2 digit ":" 2 digit ":" 2 digit]
]
parse line [ to date to end]
但是我得到了这个错误:
** Script error: PARSE - invalid rule or usage of rule: digit
** Where: parse do either either either -apply-
** Near: parse line [to date to end]
我做了一些测试:
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
由于date
值的位置在我所有的数据集中都不相同,如何才能到达并匹配它并进行相应的更改?
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
这表明它确实没有比 "naively" 在每一步迭代地应用解析规则更好的答案。循环 PARSE 引擎不如原子 运行 a TO/THRU 高效,后者存在更快的查找方法(例如,基本字符串搜索)。重复执行括号中的代码可能与实际意图不符。
还是……还是允许吧。然后让用户担心他们的代码何时变慢,并在重要时对其进行性能调整。因此 Rebol 的 Ren-C branch 很可能在这方面与 Red 保持一致,并允许任意规则。
我是通过间接方式做到的:
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)
]
输出:
{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)}
我做了如下操作:
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)}
这是一个真正的 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 "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)}
我正在研究字符串转换问题。要求是这样的:
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 "0123456789"
[4 digit "-" 2 digit "-" 2 digit space 2 digit ":" 2 digit ":" 2 digit]
]
parse line [ to date to end]
但是我得到了这个错误:
** Script error: PARSE - invalid rule or usage of rule: digit
** Where: parse do either either either -apply-
** Near: parse line [to date to end]
我做了一些测试:
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
由于date
值的位置在我所有的数据集中都不相同,如何才能到达并匹配它并进行相应的更改?
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
这表明它确实没有比 "naively" 在每一步迭代地应用解析规则更好的答案。循环 PARSE 引擎不如原子 运行 a TO/THRU 高效,后者存在更快的查找方法(例如,基本字符串搜索)。重复执行括号中的代码可能与实际意图不符。
还是……还是允许吧。然后让用户担心他们的代码何时变慢,并在重要时对其进行性能调整。因此 Rebol 的 Ren-C branch 很可能在这方面与 Red 保持一致,并允许任意规则。
我是通过间接方式做到的:
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)
]
输出:
{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)}
我做了如下操作:
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)}
这是一个真正的 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 "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)}