我有一个XML文件。
<?xml version="1.0"?>
<catalog>
<book id="bk101">
</book>
<catalog>
我读取文件并将其存储在file_data
中 set data [split $file_data "\n"]
foreach line $data {
regexp { book id=\"(.*)\" } $line all dummy
puts $all
puts $dummy
}
所以在这里,你可以看到我正在尝试阅读书籍ID并将其打印出来。 我得到错误虚拟未找到?我做错了吗?
修改
当我尝试这个时很奇怪:
set mydata {<book id="bk101"> testing the code }
puts $mydata
regexp {book id="(.*)"} $mydata all part
puts $all
puts $part
输出
<book id="bk101"> testing the code
book id="bk101"
bk101
不知道顶部的代码仍显示错误
答案 0 :(得分:3)
Don't do that(虽然这个问题是关于XHTML的,但在这方面它并不比任何其他XML方言更差;如果有任何更糟糕的话,那就是普通的HTML)。简而言之,XML属于RE 无法 完全解析的一类语言。
相反,使用tDOM来解析XML,使用XPath(由tDOM支持)来挑选文档的有趣部分。
package require tdom
# Get the XML here by whatever method, and parse it here...
set doc [dom parse $file_data]
# Iterate over the books in the document and print their IDs
foreach book [$doc selectNodes "//book"] {
puts "book with id=[$book @id]"
}
# Tidy up at the end...
$doc delete
使用tDOM进行XML处理很容易。它实际上比使用RE更容易,而且也是正确的。双赢!
答案 1 :(得分:2)
RE中的空格非常重要,您可以将它们放置在原始RE周围,而不会有任何预期。如果你想解析XML,最好使用tdom或TclXML。
你应该检查regexp的结果是否返回非零答案(意味着它找到了什么),否则'dummy'将不会被设置,或者如果先前设置的话将保持原样。
答案 2 :(得分:1)
要回答您的具体问题,您的正则表达式中会有额外的空格。仔细看看这行代码:
regexp { book id=\"(.*)\" }
注意单词本之前的空格。这很重要。你要求regexp找到一个以空格开头的字符序列,字面意思是“book”,另一个空格等。你的模式不匹配,部分原因是“book”没有出现在数据中。
答案 3 :(得分:0)
2分:
set data [split $file_data "\n"]
foreach line $data {
if { [regexp {book id=\"(.*)\"} $line all dummy] } {
puts $all
puts $dummy
}
}
您可以考虑的另一个选项,如果您可以不使用XML,并控制数据文件格式,您可以轻松创建一个人类可读的格式,并且tcl可读使您的生活更轻松
catalog {
book {
{ id "bk101" }
}
}
等。这很容易作为tcl列表阅读,并在程序中解释