2010-12-08 4 views
0

У меня есть файл XML.Справка по Regexp из xml (Tcl)

<?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 

понятия не имеют код в верхней части все еще показывает ошибку

+0

Отсутствует знак '' '' '? – Orbling

+0

Ваша проблема заключается в использовании регулярных выражений для анализа XML. Вместо этого, вы знаете, синтаксический анализатор XML. –

+0

где? вы имеете в виду regexp {book id = \ "(. *) \"} $ line $ dummy – Sii

ответ

2

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

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

0

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 и интерпретировать в программе

3

Don't do that (хотя этот вопрос касается XHTML, это не хуже, чем любой другой диалект XML в этом отношении; простой HTML - если что-то хуже). Короче говоря, XML относится к классу языков, который REs не может полностью разобрать.

Вместо этого используйте 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, и это тоже правильно. Двойной выигрыш!

+0

Хотя я в целом согласен с чувством Донала, может быть, стоит отметить, что текст, который здесь «искал» (и входной документ) может быть достаточно простым, чтобы справиться с регулярным выражением. Если все, что он делает, это вытащить этот небольшой фрагмент из документа и согласиться с тем, что вытаскивание этого текста игнорирует любой контекст, тогда это может быть достаточно хорошим. – RHSeeger

+0

@RHSeeger: Да, кроме того, что я считаю, что в этой ситуации все еще проще использовать tDOM. Это хорошо. –

+0

Также типично, что, как только лицо, принимающее решение, получает рабочее приложение, основанное на RE, которое анализирует один простой XML-фрагмент, изначально запрошенный, он находится всего в восемнадцати секундах от вопроса, почему он не работает в этом другом случае , и вскоре кодер узнал, что он пытается написать полномасштабный синтаксический анализатор XML, и все это никогда не намеревается сделать. И, да, tDOM * - это хорошо. –

1

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

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

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

Смежные вопросы