2014-02-17 4 views
1

Задача: Выражение регулярного выражения для захвата слов между двумя границами. Ниже код не работаетЗахватывающие слова в границах

regexp -- {/b/{(.+)/}}/b} $outputline8 - filtered 

Цель:

  1. Схватив все имя контакта xxx/xxx[x], который расположен после set_false_path и между { и }.
  2. Может быть другой вариант, например, «через» в пути set_false_, и я все еще хочу захватить эти контакты после этих параметров и поместить эти контакты в выходной файл так, как описано ниже.

Вот мой входной файл: input_file.txt

set_false_path -from [get_ports {AAAcc/BBB/CCC[1] \ 
BBB_1/CCC[1] CCC/DDD[1] \ 
DDD/EEE EEE/FFF[1] \ 
FFF/GGG[1]}] -through\ 
[get_pins {GGG/HHH[1] HHH/III[1] \ 
XXX/YYY[1] YYY/XXX[1] \ 
AAA/ZZZ[1]}] 
set_timing_derate -cell_sdada [get_cells \ 
{NONO[1]} 
set_false_path -from [get_ports {AAA/DDD[2]}] 

Вот выходной файл (формат я ожидал): output_file.txt

AAAcc/BBB/CCC[1] 
BBB_1/CCC[1] 
CCC/DDD[1] 
DDD/EEE 
EEE/FFF[1] 
FFF/GGG[1] 
GGG/HHH[1] 
HHH/III[1] 
XXX/YYY[1] 
YYY/XXX[1] 
AAA/ZZZ[1] 
AAA/DDD[2] 

Вообще говоря, эти выводы не имеют какой-либо общий рисунок. Таким образом, единственный способ - захватить все контакты между { и }.

Из вышеприведенного входного файла мы видим, что команды set_ (от input.txt) не подключены ни в одном предложении. Так что я сделал код, который будет только захватить содержание в set_false path и присоединиться эти строки, ниже мой код:

set inputfile [open "input_file.txt" r] 
set outputfile [open "output_file.txt" w] 

set first_word "" 
set outputline1 "" 
set filtered "" 

while { [gets $inputfile line] != 1} { 
set first_word [lindex [split $line ""] 0] 
set re2 {^set_+?} 
#match any "set_ " command 
if { [regexp $re2 $first_word matched] } { 
    #if the "set_ " command is found and the outputline1 is not empty, then it's 
    # the end of the last set_ command 
    if {$outputline1 != ""} { 
    #do the splitting here and put into the outputfile later on 
    regexp -- {/b/{(.+)/}}/b} $outputline8 - filtered 
    puts "$filtered:$filtered" 
    set outputline1 "" 
    } 

    # grab content if part of set_false_path 
    if{ [regexp "set_false_path" $first_word] } { 
    # if it's the expected command set, put "command_set" flag on which will be used on 
    # the next elseif 
    set command_set 1 
    lappend outputline1 $line 
    regsub -all {\\\[} $outputline1 "\[" outputline2 
    regsub -all {\\\]} $outputline2 "\]" outputline3 
    regsub -all {\\\{} $outputline3 "\{" outputline4 
    regsub -all {\\\}} $outputline4 "\}" outputline5 
    regsub -all {\\\\} $outputline5 "\\" outputline6 
    regsub -all {\\ +} $outputline6 " " outputline7 
    regsub -all {\s+} $outputline7 " " outputline8 
    } else { 
    set command_set 0 
    # if the line isn't started with set_false_path but it's part of set_false_path command 
    } elseif {$command_set} { 
    lappend outputline1 $line 
    regsub -all {\\\[} $outputline1 "\[" outputline2 
    regsub -all {\\\]} $outputline2 "\]" outputline3 
    regsub -all {\\\{} $outputline3 "\{" outputline4 
    regsub -all {\\\}} $outputline4 "\}" outputline5 
    regsub -all {\\\\} $outputline5 "\\" outputline6 
    regsub -all {\\ +} $outputline6 " " outputline7 
    regsub -all {\s+} $outputline7 " " outputline8 
    } else { 
    } 
} 
} 

puts "outputline:outputline8" 
#do the splitting here and put into the file later on for the last grabbed line! 

close $inputfile 
close $outputfile 

Код углубленного обсуждения:

  • Я заметил, что после того, как я внахлест линию для outputline1, я буду получать неожиданный выход с несколькими пространствами и прямой слэш: set_false_path\ -from\ \[get_ports\ \{AAA/BBB\[1\] \ ... и т.д ..

    Этот вывод содержит пробелы (\) для каждого специального символа, такого как {, [, пробел и т. Д. Поэтому я помещаю много regsub, чтобы удалить все эти ненужные добавления.И последний присоединился результат находится в $ outputline8

    Результат $ outputline8:

    set_false_path -from [get_ports {AAAcc/BBB/CCC[1] BBB_1/CCC[1] CCC/DDD[1] DDD/EEE EEE/FFF[1] FFF/GGG[1]}] -through [get_pins {GGG/HHH[1] HHH/III[1] XXX/YYY[1] YYY/XXX[1] AAA/ZZZ[1]}] 
    set_false_path -from [get_ports {AAA/DDD[2]}] 
    
  • Я планирую захватить и разделить штифт внутри outputline8 в { и }

Код: process multiple lines text file to print in single line

  • вот последний UPDATE START:

    Если входной файл:

    set_false_path -from [get_ports {AAAcc/BBB/CCC[1] BBB_1/CCC[1] DDD/EEE}] -through [get_pins {XXX_1[1]}] 
    

    Я хочу, чтобы выходной файл:

    AAAcc/BBB/CCC[1] 
    BBB_1/CCC[1] 
    DDD/EEE 
    XXX_1[1] 
    

Спасибо! вот последний UPDATE END:

NB: Я новичок в TCL и этот форум и любые советы действительно оценили!

+0

Нельзя ли иметь обратную косую черту вместо косых черт в '{/ b /{(.+)/}}/ b}'? '{\ b \ {(. +) \}} \ b}' – devnull

+0

Да, devnull .. Я глуп :(Я пробовал {/b/{(.+)/}}/b}, но он не " т работа ни –

+0

я пытался использовать 'регулярное выражение - {\ {\} (+.)} $ outputline8 - filtered' Но я получаю: ' AAAcc/ВВВ [1] BBB_1/CCC [1 ] CCC/DDD [1] DDD/EEE EEE/FFF [1] FFF/GGG [1]}] - через [get_pins {GGG/HHH [1] HHH/III [1] XXX/YYY [1] YYY/XXX [1] AAA/ZZZ [1] ' Похоже, это будет получить первый "{" до последнего "}" Но я хочу: ' AAAcc/ВВВ [1] BBB_1/CCC [1] CCC/DDD [1] DDD/EEE EEE/FFF [1] FFF/GGG [1] GGG/HHH [1] HHH/III [1] XXX/YYY [1] YYY/XXX [1] AAA/ZZZ [1] ' Спасибо! –

ответ

0

Пробуйте следующий сценарий. Я добавил объяснения в комментарии коментариев:

set inputfile [open "input_file.txt" r] 
set outputfile [open "output_file.txt" w] 

# This is a temp variable to store the partial lines 
set buffer "" 

while { [gets $inputfile line] != -1} { 
    # Take previous line and add to current line 
    set buffer "$buffer[regsub -- {\\[[:blank:]]*$} $line ""]" 

    # If there is no ending \ then stop adding and process the elements to extract 
    if {![regexp -- {\\[[:blank:]]*$} $line]} { 
    # Skip line if not "set_false_path" 
    if {[lindex [split $buffer " "] 0] ne "set_false_path"} { 
     set buffer "" 
     continue 
    } 

    # Grab each element with regexp into a list and print each to outputfile 
    # m contains whole match, groups contains sub-matches 
    foreach {m groups} [regexp -all -inline -- {\{([^\}]+)\}} $buffer] { 
     foreach out [split $groups] { 
     puts $outputfile $out 
     } 
    } 

    # Clear the temp variable 
    set buffer "" 
    } 
} 

close $inputfile 
close $outputfile 
+0

Hay Jerry, я получил сообщение об ошибке: дополнительные символы после закрытия цитаты. Кстати, я думаю, что открываю новую тему, так как во входном файле есть новая модификация. Пожалуйста, помогите мне в новой теме! –

+0

@ AndiLee О? Какую версию Tcl вы используете? Я думаю, что причиной ошибки является '' $ buffer [regsub - {\\ [[: blank:]] * $} $ line ""] "'. Не могли бы вы попробовать '$ buffer [regsub - {\\ [[: blank:]] * $} $ line" "]'? Я проверяю новый вопрос тем временем. – Jerry

+0

@AndiLee Кроме того, я не думаю, что есть необходимость задать другой вопрос, если входной файл сильно отличается.Но тогда, что будет с этим вопросом? – Jerry

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