如何在TCL中使用regexp来匹配文件中的一行?
我是TCL的新手。因此,我被要求从文件中提取开始日期,但我尝试了,没有输出。请帮忙 从我的文件中,有一行我想提取开始日期:如何在TCL中使用regexp来匹配文件中的一行?,tcl,Tcl,我是TCL的新手。因此,我被要求从文件中提取开始日期,但我尝试了,没有输出。请帮忙 从我的文件中,有一行我想提取开始日期: Running final_step.step_done at: Wed Oct 11 02:04:03 MYT 2017 我的代码: proc extract_data {} { ## To extract startdate set file [open files/stages.files] while {[gets $file line]
Running final_step.step_done at: Wed Oct 11 02:04:03 MYT 2017
我的代码:
proc extract_data {} {
## To extract startdate
set file [open files/stages.files]
while {[gets $file line] >= 0} {
if {[regexp {^Running (\S+\s)at: (\S+.*)$} $line match Stage StartDate]} {
if {[regexp "[$CURRENT_STAGE]\.step_done" $Stage]} {
#set stage $Stage
set end_date $StartDate
set print_end_date [regsub -all " " $StartDate "_"]
#echo "2) $stage - $end_date"
} elseif {[regexp "^[$CURRENT_STAGE] " $Stage]} {
#set stage $Stage
set start_date $StartDate
set print_start_date [regsub -all " " $StartDate "_"]
#echo "1) $stage - $start_date"
}
}
}
我的regexp有什么问题吗?主RE看起来很好-
^运行(\S+\S)在:(\S+.*)$
确实与您所说的行匹配-但是这些RE匹配看起来可疑:
regexp "[$CURRENT_STAGE]\.step_done" $Stage
特别是,这里有一个命令替换,命令名来自一个变量。这…在某些情况下是有效的,但这是一项相当先进的技术;你确定这就是你想要的吗?另外,CURRENT_STAGE
变量似乎未声明。我希望其中一种方法更有可能奏效:
变量替换
这里,我们使用的是变量名的限定版本。请注意,变量最好包含一个有效的正则表达式片段,我们需要将反斜杠加倍(因为我们处于双引号上下文而不是大括号上下文中;一个反斜杠用于基本Tcl语言,另一个用于re引擎)
命令替换
在这里,我们调用一个命令来获取实际的阶段。命令最好返回一个有效的RE片段,和前面一样,我们将反斜杠加倍
regexp "[CURRENT_STAGE]\\.step_done" $Stage
一般来说,在这两种情况下,您可能会考虑在代码< >(.://>代码>…>代码> 中包装代表当前阶段的RE部分,因为这并不能真正改变语义,但这意味着RE片段可以使用安全交互的特征。当重新片段是一个简单的事情,比如
最后一步
时,这并不重要。在我看来,您应该能够用这样的代码完成很多工作:
while {[gets $file line] >= 0} {
if {[string match Running $line]} {
set Stage [lindex [split $line] 1]
set StartDate [lindex [string trim [split $line :]] end]
if {[string match *.step_done $Stage]} {
set end_date $StartDate
set print_end_date [string map {" " _} $StartDate]
} else {
set start_date $StartDate
set print_start_date [string map {" " _} $StartDate]
}
}
}
就是
- 检查该行是否以“Running”开头
- 将“Running”和“at:”之间的字符串放入
Stage
- 获取“:”之后的日期字符串,输入
StartDate
- 检查
$Stage
- 如果有,请将
设置为结束日期
并将$StartDate
设置为同一字符串,所有空格均替换为下划线打印结束日期
- 如果尾部为空,则对
和开始日期
打印开始日期
您要查找的行的开头(和结尾)是否有星号?如果有,
^Running
将与行不匹配。我的代码中没有*。当我将代码设置为斜体时,似乎产生了*。感谢您指出。在第一个if
之后,尝试输出阶段
和开始日期
变量?我觉得这个问题确实与下一组IF块有关。变量<代码>阶段<代码>捕获阶段描述符和字符串“AT:”之间的空白。下一次调用<代码> ReXEP < /C> >忽略空白(<代码>)[$CurrutyField],StdithOn“”,而<<代码> ELSIF < /C> >(<代码> > [$CurrutyPosi] ] /<代码>没有。如果空白只是将描述符与“AT::string”分隔开来,不要捕获它。其中任何一个都应该有输出,但这肯定会导致问题。
regexp "^$::CURRENT_STAGE " $Stage
regexp "[CURRENT_STAGE]\\.step_done" $Stage
regexp "^[CURRENT_STAGE] " $Stage
while {[gets $file line] >= 0} {
if {[string match Running $line]} {
set Stage [lindex [split $line] 1]
set StartDate [lindex [string trim [split $line :]] end]
if {[string match *.step_done $Stage]} {
set end_date $StartDate
set print_end_date [string map {" " _} $StartDate]
} else {
set start_date $StartDate
set print_start_date [string map {" " _} $StartDate]
}
}
}