英文:
mismatch in the regular expression - Tcl script
问题
在这个文件中,我想使用正则表达式获取一些信息,但它给我一些错误的数据。
其中 $line 是:
+ ROUTED M12 10000 + SHAPE STRIPE ( 22636 * ) ( 41810 89000 )
情境: 与 ROUTED 不同,有些行包括 FIXED, COVER, SHIELD
正则表达式和我编写的一些代码如下:
if {[string match {*ROUTED*|*FIXED*|*COVER*|*SHIELD*} $line]} {
set RE {(\s*\+\s*(ROUTED|FIXED|COVER|SHIELD)[^(]+\(\s*)([^\s()]+)\s+([^\s()]+)\s*\)\s*\(\s*([^\s()]+)\s+([^\s()]+)\s*\)}
if {[regexp $RE $line -> match1 Vxx Vxy Vyx Vyy]} {
set match1 $match1
set Vxx $Vxx
set Vxy $Vxy
set Vyx $Vyx
set Vyy $Vyy
puts $match1
puts $Vxx
puts $Vxy
puts $Vyx
puts $Vyy
}
}
这里给出的输出是:
+ ROUTED M12 10000 + SHAPE STRIPE (
ROUTED
22636
*
41810
而我的期望结果是:
+ ROUTED M12 10000 + SHAPE STRIPE (
22636
*
41810
89000
在我的代码中有什么问题,有人能帮我调试吗?
英文:
In the file i want to fetch some information using regular expressions, but it's giving me some wrong data.
where $line is:
+ ROUTED M12 10000 + SHAPE STRIPE ( 22636 * ) ( 41810 89000 )
Pov: instead of ROUTED Some lines consist of FIXED, COVER, SHIELD
the regex and some code what i wrote
if {[string match {*ROUTED*|*FIXED*|*COVER*|*SHIELD*} $line]} {
set RE {(\s*\+\s*(ROUTED|FIXED|COVER|SHIELD)[^(]+\(\s*)([^\s()]+)\s+([^\s()]+)\s*\)\s*\(\s*([^\s()]+)\s+([^\s()]+)\s*\)}
if {[regexp $RE $line -> match1 Vxx Vxy Vyx Vyy]} {
set match1 $match1
set Vxx $Vxx
set Vxy $Vxy
set Vyx $Vyx
set Vyy $Vyy
puts $match1
puts $Vxx
puts $Vxy
puts $Vyx
puts $Vyy
}
}
where this giving me output as
+ ROUTED M12 10000 + SHAPE STRIPE (
ROUTED
22636
*
41810
where my expected result is
+ ROUTED M12 10000 + SHAPE STRIPE (
22636
*
41810
89000
what's the wrong in the code can anyone debug my code?
答案1
得分: 2
如果你要的只是代码部分的中文翻译,那么以下是代码的中文翻译:
如果你觉得你的正则表达式难以阅读和维护,可以尝试这个不依赖正则表达式,只依赖列表位置的替代方法,只要你解析的每一行都满足 Tcl 正确列表的要求。
if {[lindex $line 1] in {ROUTED FIXED COVER SHIELD}} {
if {[llength $line] == 15} {
foreach i {8 9 12 13} {
puts [lindex $line $i]
}
}
}
另一个替代方法是使用 `scan` 命令:
scan $line "+ %s %s %s + %s %s ( %s %s ) ( %s %s )" status layer len type1 type2 Vxx Vxy Vyx Vyy
if {$status in {ROUTED FIXED COVER SHIELD}} {
puts $Vxx
puts $Vxy
puts $Vyx
puts $Vyy
}
英文:
I find your regex very difficult to read and maintain.
If each line you parse meets the requirements of a Tcl proper list, then try this alternative that doesn't rely regular expressions, but only positions in a list.
if {[lindex $line 1] in {ROUTED FIXED COVER SHIELD}} {
if {[llength $line] ==15} {
foreach i {8 9 12 13} {
puts [lindex $line $i]
}
}
}
--> 22636
*
41810
89000
Another alternative is the scan
command:
scan $line "+ %s %s %s + %s %s ( %s %s ) ( %s %s )" status layer len type1 type2 Vxx Vxy Vyx Vyy
if {$status in {ROUTED FIXED COVER SHIELD}} {
puts $Vxx
puts $Vxy
puts $Vyx
puts $Vyy
}
答案2
得分: 1
你想要(ROUTED|FIXED|COVER|SHIELD)
被匹配为一组备选项,但不报告为子匹配。尝试使用(?:ROUTED|FIXED|COVER|SHIELD)
- 参见https://www.tcl-lang.org/man/tcl8.6/TclCmd/re_syntax.htm#M16
英文:
You want (ROUTED|FIXED|COVER|SHIELD)
to be matched as a group of alternatives but not reported as a sub-match. Try using (?:ROUTED|FIXED|COVER|SHIELD)
- see https://www.tcl-lang.org/man/tcl8.6/TclCmd/re_syntax.htm#M16
答案3
得分: 0
if {[string match {ROUTED} $line] || [string match {FIXED} $line] || [string match {COVER} $line] || [string match {SHIELD} $line]} {
puts $line
set RE {(\s*\+\s*(FIXED|ROUTED)[^(]+\(\s*)([^\s()]+)\s+([^\s()]+)\s*\)\s*\(\s*([^\s()]+)\s+([^\s()]+)\s*\)}
if {[regexp $RE $line -> match1 match2 Vxx Vxy Vyx Vyy]} {
<details>
<summary>英文:</summary>
if {[string match {*ROUTED*} $line] || [string match {*FIXED*} $line] || [string match {*COVER*} $line] || [string match {*SHIELD*} $line]} {
puts $line
set RE {(\s*\+\s*(FIXED|ROUTED)[^(]+\(\s*)([^\s()]+)\s+([^\s()]+)\s*\)\s*\(\s*([^\s()]+)\s+([^\s()]+)\s*\)}
if {[regexp $RE $line -> match1 match2 Vxx Vxy Vyx Vyy]} {
the regular expression is correct but there is a change in if condition and it will work as per my requirement.
thanks for the effort.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论