Проверьте CSV на данный формат

Я ожидаю, что пользователи загружат файл CSV с максимальным размером 1 МБ в веб-форму, которая должна соответствовать формату, подобному:

"<String>","<String>",<Int>,<Float> 

Это будет обработано позже. Я хотел бы подтвердить, что файл соответствует указанному формату, так что программа, которая позже будет использовать файл, не получит неожиданного ввода и что нет проблем с безопасностью (скажем, инъекция для скрипта синтаксического анализа, которая выполняет некоторые вычисления и вставка db).

(1) Что было бы лучшим способом сделать это, чтобы быть быстрым и тщательным? Из того, что я исследовал, я мог пойти по пути регулярного выражения или чего-то большего подобного. Я просмотрел модуль csv python, но, похоже, он не имеет встроенной проверки.

(2) Предполагая, что я иду на регулярное выражение, может ли кто-нибудь направить меня к лучшему способу сделать это? Согласны ли я с незаконными символами и отказываюсь от этого? (например, no '/' '\' '<' '>' '{' '}' и т. д.) или совпадать со всеми юридическими, например. [a-zA-Z0-9] {1,10} для строкового компонента? Я не слишком хорошо знаком с регулярными выражениями, поэтому оценщики и примеры будут оценены.

EDIT: Строки не должны содержать запятых или кавычек, в которых просто будет указано имя (то есть имя, фамилия). И да, я забыл добавить, что они будут двойными.

EDIT # 2: Спасибо за все ответы. Cutplace довольно интересна, но является автономной. В конце концов решила пойти с pyparsing, потому что это дает большую гибкость, если я добавлю больше форматов.

6 Solutions collect form web for “Проверьте CSV на данный формат”

Pyparsing обработает эти данные и будет терпимо к непредвиденным вещам, таким как пробелы до запятых и после них, запятые в кавычках и т. Д. (Csv-модуль тоже, но регулярные решения заставляют вас добавлять «\ s *» биты повсюду) ,

 from pyparsing import * integer = Regex(r"-?\d+").setName("integer") integer.setParseAction(lambda tokens: int(tokens[0])) floatnum = Regex(r"-?\d+\.\d*").setName("float") floatnum.setParseAction(lambda tokens: float(tokens[0])) dblQuotedString.setParseAction(removeQuotes) COMMA = Suppress(',') validLine = dblQuotedString + COMMA + dblQuotedString + COMMA + \ integer + COMMA + floatnum + LineEnd() tests = """\ "good data","good2",100,3.14 "good data" , "good2", 100, 3.14 bad, "good","good2",100,3.14 "bad","good2",100,3 "bad","good2",100.5,3 """.splitlines() for t in tests: print t try: print validLine.parseString(t).asList() except ParseException, pe: print pe.markInputline('?') print pe.msg print 

Печать

 "good data","good2",100,3.14 ['good data', 'good2', 100, 3.1400000000000001] "good data" , "good2", 100, 3.14 ['good data', 'good2', 100, 3.1400000000000001] bad, "good","good2",100,3.14 ?bad, "good","good2",100,3.14 Expected string enclosed in double quotes "bad","good2",100,3 "bad","good2",100,?3 Expected float "bad","good2",100.5,3 "bad","good2",100?.5,3 Expected "," 

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

 dblQuotedString.setParseAction(removeQuotes) 

Если вы хотите добавить поддержку комментариев в свой входной файл, скажем, «#», за которым следует остальная часть строки, вы можете сделать это:

 comment = '#' + restOfline validLine.ignore(comment) 

Вы также можете добавлять имена в эти поля, чтобы вы могли получить к ним доступ по имени вместо позиции индекса (который я нахожу, дает более надежный код в свете изменений по дороге):

 validLine = dblQuotedString("key") + COMMA + dblQuotedString("title") + COMMA + \ integer("qty") + COMMA + floatnum("price") + LineEnd() 

И ваш код последующей обработки может затем сделать следующее:

 data = validLine.parseString(t) print "%(key)s: %(title)s, %(qty)d in stock at $%(price).2f" % data print data.qty*data.price 

Я проголосовал за разбор файла, проверив, что у вас есть 4 компонента на запись, что первые два компонента – это строки, третий – int (проверка для условий NaN), а четвертый – float (также проверка на NaN условия).

Python будет отличным инструментом для работы.

Я не знаю о каких-либо библиотеках в Python, чтобы иметь дело с проверкой файлов CSV против спецификации, но это не должно быть слишком сложно писать.

 import csv import math dataChecker = csv.reader(open('data.csv')) for row in dataChecker: if len(row) != 4: print 'Invalid row length.' return my_int = int(row[2]) my_float = float(row[3]) if math.isnan(my_int): print 'Bad int found' return if math.isnan(my_float): print 'Bad float found' return print 'All good!' 

Вот небольшой фрагмент, который я сделал:

 import csv f = csv.reader(open("test.csv")) for value in f: value[0] = str(value[0]) value[1] = str(value[1]) value[2] = int(value[2]) value[3] = float(value[3]) 

Если вы запустите это с файлом, у которого нет указанного формата, вы получите исключение:

 $ python valid.py Traceback (most recent call last): File "valid.py", line 8, in <module> i[2] = int(i[2]) ValueError: invalid literal for int() with base 10: 'a3' 

Затем вы можете сделать try-except ValueError, чтобы поймать его и сообщить пользователям, что они сделали неправильно.

Может быть много угловых случаев для синтаксического анализа CSV, поэтому вы, вероятно, не захотите делать это «вручную». По крайней мере, начните с встроенного пакета / библиотеки на язык, который вы используете, даже если он не выполняет всю «проверку», о которой вы можете думать.

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

Вы также можете запретить встроенные \ r или \ n, \ 0 или \ t. Просто пройдите по полям и проверьте их после загрузки данных с помощью csv lib.

Попробуйте Cutplace . Он проверяет, что данные табуляции соответствуют документу управления интерфейсом .

В идеале, вы хотите, чтобы ваша фильтрация была как можно более ограничительной – чем меньше вы позволяете, тем меньше потенциальных возможностей атаки. Например, поле float или int имеет очень малое количество символов (и очень мало конфигураций этих символов), которые фактически должны быть разрешены. Фильтрация строк в идеале должна быть ограничена только тем, что у людей у ​​людей есть причина для ввода – не зная более обширного контекста, трудно сказать вам точно, что вы должны разрешить, но на минимальном уровне регулярное выражение в строке должно требовать цитирования строк и запрета все, что рано или поздно закончило бы строку.

Однако имейте в виду, что некоторые имена могут содержать такие вещи, как одиночные кавычки (например, «O'Neil») или тире, поэтому вы не можете их исключить.

Что-то вроде…

 /"[a-zA-Z' -]+"/ 

… вероятно, будет идеальным для строк с двумя кавычками, которые должны содержать имена. Вы могли бы заменить + с длиной {x,y} длиной min / max, если вы хотите также использовать определенные длины.

  • IPv6 regexp python
  • Python re.sub с флагом не заменяет все вхождения
  • Цитирование через регулярные выражения python
  • Существует ли эквивалент Python для модификатора Perl «/ x» для регулярных выражений?
  • Регулярное выражение с unicode и str
  • PyCharm 3.1 постоянно висит во время индексации и непригодности
  • REGEX отличается от PHP до Python
  • множественная замена регулярных выражений в нескольких файлах с использованием python
  •  
    Interesting Posts for Van-Lav

    Кажется, что Django кэширует datetime.now ()

    Встраивание тензорного потока не существует после первого примера RNN

    Как правильно вызвать методы базового класса (и конструктор) из унаследованных классов в Python?

    Создание графика с определенным распределением степени?

    Плавная реализация MATLAB (n-точечная скользящая средняя) в NumPy / Python

    Как вызвать функцию со словарем, который содержит больше элементов, чем функция имеет параметры?

    Убить процесс python с pkill python

    Дизайн абстрактного / интерфейса Java в Python

    Проблемы с python genfromtxt

    В Python, как я могу ссылаться на класс в общем статическом ключе, например на ключевое слово PHP?

    shopify скрипт не вставляет скриптовый тег для хранения

    булевское индексирование, которое может привести к представлению большого массива данных панд?

    Django не запускается с ошибкой wierd. Объект 'AttributeError:' module 'не имеет атрибута' getargspec ''

    python numpy фильтрует два размерных массива по условию

    Присвоение возвращаемого значения функции переменной, с многопроцессорной обработкой? И проблема с IDLE?

    Python - лучший язык программирования в мире.