我是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] >= 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"
}
}
}
我的正则表达式有问题吗?
答案 0 :(得分:1)
主RE看起来很好 - <!DOCTYPE html>
<hmtl>
<head>
<meta charset="UTF-8">
<title>Canvas</title>
<style type="text/css">
canvas{
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvasOne" ></canvas>
<script type="text/javascript">
// Gets a handle to the element with id canvasOne.
var canvas = document.getElementById("canvasOne");
// Set the canvas up for drawing in 2D.
var ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 500;
function Ball(xpos, ypos, r) {
this.xpos = xpos;
this.ypos = ypos;
this.r = r;
this.move = function(addx, addy) {
this.xpos = this.xpos + addx;
this.ypos = this.ypos + addy;
};
this.resize = function(setr) {
this.r = setr;
};
this.draw = function() {
for (var i = 0; i < 7; i++) {
ctx.beginPath();
ctx.moveTo(this.xpos, this.ypos);
ctx.arc(this.xpos, this.ypos, this.r, i * (2 * Math.PI / 7), (i + 1) * (2 * Math.PI / 7));
ctx.lineWidth = 2;
ctx.stroke();
}
ctx.beginPath();
ctx.moveTo(this.xpos, this.ypos);
ctx.arc(this.xpos, this.ypos, this.r - 10, 0, 2 * Math.PI);
ctx.lineWidth = 2;
ctx.stroke();
};
this.spin = function() {
var angle = 0;
this.angle = (this.angle + 1) % 360;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(this.xpos,this.ypos);
ctx.rotate( this.angle*Math.PI/180 );
ctx.translate(-this.xpos,-this.ypos);
ctx.beginPath();
this.draw();
ctx.restore();
};
this.contains = function(x, y) {
this.x = this.x;
this.y = this.y;
if (Math.sqrt((x - this.xpos) * (x - this.xpos) + (y - this.ypos) * (y - this.ypos)) <= this.r) {
return true;
} else {
return false;
}
};
//put "ball" as a paremeter
//ball will be the foreign Ball to test intersection against
this.intersect = function(ball) {
var productX = this.xpos - ball.xpos;
var productY = this.ypos - ball.ypos;
var distance = Math.sqrt(productX * productX + productY * productY);
if (distance <= (this.r + ball.r)) {
return true;
} else {
return false;
}
};
}
var ball1 = new Ball(100, 100, 100);
ball1.draw();
ball1.spin();
setInterval(ball1.spin,100);
</script>
</body>
</html>
确实与你所说的那条线匹配 - 但这些RE匹配看起来很可疑:
^Running (\S+\s)at: (\S+.*)$
regexp "[$CURRENT_STAGE]\.step_done" $Stage
特别是,你在那里有一个命令替换,命令的名称来自变量。那是......在某些情况下有效,但是相当先进的技术;你肯定这是你想要的吗?此外,regexp "^[$CURRENT_STAGE] " $Stage
变量似乎未声明。我希望其中一种方法更有可能发挥作用:
在这里,我们使用变量名称的限定版本。请注意,变量最好包含一个有效的正则表达式片段,我们需要加倍反斜杠(因为我们处于双引号上下文而不是支撑上下文;一个反斜杠用于基本Tcl语言,另一个反斜杠用于基本Tcl语言,另一个是RE引擎)。
CURRENT_STAGE
regexp "$::CURRENT_STAGE\\.step_done" $Stage
在这里,我们正在调用命令来获得实际阶段。该命令最好返回一个有效的RE片段,和以前一样,我们将反斜杠加倍。
regexp "^$::CURRENT_STAGE " $Stage
regexp "[CURRENT_STAGE]\\.step_done" $Stage
通常,在这两种情况下,您可能会考虑在regexp "^[CURRENT_STAGE] " $Stage
... (?:
中包装代表当前阶段的RE部分,因为这并没有真正改变语义,但确实意味着RE片段可以安全地使用交替等功能。当RE片段像)
一样简单时,并不重要。
答案 1 :(得分:0)
在我看来,你应该可以用这样的代码完成很多工作:
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]
}
}
}
即,
Stage
StartDate
$Stage
end_date
设置为$StartDate
,将print_end_date
设置为相同的字符串,并将所有空格替换为下划线start_date
和print_start_date
文档: >= (operator), gets, if, lindex, set, split, string, while