从xml(Tcl)帮助Regexp

时间:2010-12-08 02:38:35

标签: xml regex tcl

我有一个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

不知道顶部的代码仍显示错误

4 个答案:

答案 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分:

  1. 如果您正在阅读数据行 行,你需要检查regexp 实际上在阅读前做了一个匹配 变量
  2. 杰夫是对的,你还有一个额外的 开头和结尾都有空格 你的正则表达式
  3. 
      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列表阅读,并在程序中解释