Регулярное выражение для анализа CSV? Python3 Re модуль - PullRequest
0 голосов
/ 19 июня 2020

Есть ли регулярное выражение (Python re-совместимое), которое я могу использовать для синтаксического анализа csv? Было бы предпочтительнее объяснить, как это работает. Я хотел бы получить все значения из файла csv в этом формате:

[

[item1_of_row1, item2_of_row1, item3_of_row1, ...],

[item1_of_row2, ...]

]

И иногда файл csv беспорядочный, поэтому было бы неплохо использовать фильтр.

1 Ответ

0 голосов
/ 19 июня 2020

Вот регулярное выражение: (?<!,\"\w)\s*,(?!\w\s*\",). Он совместим с python и JavaScript. Вот полный скрипт синтаксического анализа (как функция python):

def parseCSV(csvDoc, output_type="dict"):
    from re import compile as c
    from json import dumps
    from numpy import array

    # This is where all the parsing happens
    """
    To parse csv files.
    Arguments:
    csvDoc - The csv document to parse.
    output_type - the output type this
                function will return
    """
    csvparser = c('(?<!,\"\\w)\\s*,(?!\\w\\s*\",)')
    lines = str(csvDoc).split('\n')

    # All the lines are not empty
    necessary_lines = [line for line in lines if line != ""]

    All  = array([csvparser.split(line) for line in necessary_lines])

    if output_type.lower() in ("dict", "json"):  # If you want JSON or dict
        # All the python dict keys required (At the top of the file or top row)
        top_line   = list(All[0])
        main_table = {}      # The parsed data will be here
        main_table[top_line[0]] = {
            name[0]: {
                thing: name[
                    # The 'actual value' counterpart
                    top_line.index(thing)
                ] for thing in top_line[1:]  # The requirements
            } for name in All[1:]
        }
        return dumps(main_table, skipkeys=True, ensure_ascii=False, indent=1)
    elif output_type.lower() in ("list",
                                 "numpy",
                                 "array",
                                 "matrix",
                                 "np.array",
                                 "np.ndarray",
                                 "numpy.array",
                                 "numpy.ndarray"):
        return All
    else:
        # All the python dict keys required (At the top of the file or top row)
        top_line   = list(All[0])
        main_table = {}      # The parsed data will be here
        main_table[top_line[0]] = {
            name[0]: {
                thing: name[
                    # The 'actual value' counterpart
                    top_line.index(thing)
                ] for thing in top_line[1:]  # The requirements
            } for name in All[1:]
        }
        return dumps(main_table, skipkeys=True, ensure_ascii=False, indent=1)

Зависимости: NumPy Все, что вам нужно сделать, это вставить необработанный текст файла csv и тогда функция вернет json (или двумерный список, если вы используете sh) в следующем формате:

{"top-left-corner name":{
     "foo":{"Item 1 left to foo":"Item 2 of the top row",
            "Item 2 left to foo":"Item 3 of the top row",
             ...}
     "bar":{...}
  }
}

И вот его пример: CSV.csv

foo,bar,zbar
foo_row,foo1,,
barie,"2,000",,

, и он выводит:

{
 "foo": {
  "foo_row": {
   "bar": "foo1",
   "zbar": ""
  },
  "barie": {
   "bar": "\"2,000\"",
   "zbar": ""
  }
 }
}

Он должен работать, если ваш файл csv отформатирован правильно (те, которые я тестировал, были сделаны Numbers)

...