TCL Regex для сопоставления неэкранированных кавычек в CSV - PullRequest
2 голосов
/ 23 октября 2019

Я прошел несколько вопросов и ответов здесь, чтобы решить эту проблему с CSV, у меня есть.

Вот пример CSV с неэкранированными кавычками в 5 "-

"522","-1","12345678","12345678","Completed","","","","height 5' 5" and weight 170lbs","","","9876543","ABCD","2016-06-12T23:54:00-05:00","2016-06-12T23:59:00-05:00"

Я уже использовал это предложение здесь: Соответствует неэкранированным кавычкамв кавычках csv и (?<!^|",)"(?!,|$) регулярное выражение работает прекрасно, но в контексте PHP.

Моя цель состоит в том, чтобы сопоставить одну двойную кавычку ("), которая заключена в двойные кавычки ("), но вконтекст TCL. Есть предложения? Большое спасибо!

Ответы [ 2 ]

2 голосов
/ 23 октября 2019

Поскольку вопрос, на который вы ссылаетесь, касается удаления"диких" двойных кавычек внутри полей CSV, все, что вам нужно сделать, - это преобразовать lookbehind в группу захвата с выражением с отрицательной скобкой:

set a {"522","-1","12345678","12345678","Completed","","","","height 5' 5" and weight 170lbs","","","9876543","ABCD","2016-06-12T23:54:00-05:00","2016-06-12T23:59:00-05:00"}
set result [regsub -all {([^,])"(?=[^,])} $a "\\1"]
puts $result

См. онлайн Tcl демо , вывод:

"522","-1","12345678","12345678","Completed","","","","height 5' 5 and weight 170lbs","","","9876543","ABCD","2016-06-12T23:54:00-05:00","2016-06-12T23:59:00-05:00"

([^,])"(?=[^,]) соответствует регулярному выражению

  • ([^,]) -Группа 1 (далее с \1): любой символ, кроме ,
  • " - двойная кавычка
  • (?=[^,]) - положительный прогноз, требующий другого символа, кромезапятая должна отображаться справа от текущего местоположения.
0 голосов
/ 23 октября 2019

Возможно, вы захотите разделить вместо этого, так что вы также можете выполнить дополнительные проверки на линии CSV. Я бы предложил что-то вроде следующего с помощью пакета csv по умолчанию :

package require csv

set input {"522","-1","12345678","12345678","Completed","","","","height 5' 5" and weight 170lbs","","","9876543","ABCD","2016-06-12T23:54:00-05:00","2016-06-12T23:59:00-05:00"}

# Quick check the line, if it's not complete...
if {![::csv::iscomplete $input]}    
    # Replace all 'quote comma quote' with null character (or some other character you are certain is 
    # not in your csv line
    set intermediate [regsub -all {","} $input \0]

    # Split on null character (or the character you picked on the previous line)
    set columns [split $intermediate \0]

    # Ensure that the csv line contains the expected number of columns
    if {[llength $columns] == 15} {
        # Replace the quotes in each element of the list of columns
        set columns [lmap x $columns {string map {{"} {}} $x}]
    } else {
        # Do further checks otherwise to see what's wrong
    }
    puts "Split data:"
    puts $columns        
} else {
    set columns [::csv::split -alternate $input]
}
set output [::csv::join $columns "," always]
puts "\nRejoined (if you still need it):"
puts $output

Выходы:

Split data:
522 -1 12345678 12345678 Completed {} {} {} {height 5' 5 and weight 170lbs} {} {} 9876543 ABCD 2016-06-12T23:54:00-05:00 2016-06-12T23:59:00-05:00

Rejoined (if you still need it):
"522","-1","12345678","12345678","Completed","","","","height 5' 5 and weight 170lbs","","","9876543","ABCD","2016-06-12T23:54:00-05:00","2016-06-12T23:59:00-05:00"

Таким образом, вы сможете лучше контролировать то, чтопроисходит и потенциально может найти какие-либо другие проблемы с CSV.

...