Помогите с Regexp из xml (Tcl) - PullRequest
       38

Помогите с Regexp из xml (Tcl)

0 голосов
/ 08 декабря 2010

У меня есть файл 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
 }

Итак, как вы видите, я пытаюсь прочитать идентификатор книги и распечатать его. Я получаю ошибку, манекен не найден? Я делаю это неправильно?

Редактировать

Странно, когда я пытаюсь это:

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 ]

3 голосов
/ 08 декабря 2010

Не делайте этого (хотя этот вопрос касается 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, и это тоже правильно.Двойной выигрыш!

2 голосов
/ 08 декабря 2010

Пробелы в RE значительны, и вы размещаете их вокруг оригинального RE там, где их не будет.Однако, если вы хотите проанализировать XML, лучше использовать tdom или TclXML.

Вам следует проверить, что результат регулярного выражения возвращает ненулевой ответ (что означает, что он что-то нашел), в противном случае «фиктивный» выигралне устанавливается или останется таким, как было ранее.

1 голос
/ 08 декабря 2010

Чтобы ответить на ваш конкретный вопрос, в вашем регулярном выражении есть лишние пробелы. Посмотрите внимательно на эту строку кода:

regexp { book id=\"(.*)\" }

Обратите внимание на пробел перед словом book. Это важно. Вы просите регулярное выражение найти последовательность символов, которая начинается с пробела, буквального слова «книга», другого пробела и т. Д. Ваш шаблон не совпадает, отчасти потому, что в данных не отображается «книга».

0 голосов
/ 08 декабря 2010

2 Балла:

  1. Если вы читаете данные построчно, вам нужно проверить, что регулярное выражение действительно соответствует, прежде чем читать переменные
  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 и интерпретировать в программе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...