Разобрать файл TSV - PullRequest
       23

Разобрать файл TSV

4 голосов
/ 09 марта 2010

Мне нужно проанализировать файл в формате TSV (значения, разделенные табуляцией). Я использую регулярное выражение, чтобы разбить файл на каждую строку, но я не могу найти подходящее для анализа каждой строки. А пока я придумал это:

(?<g>("[^"]+")+|[^\t]+)

Но это не работает, если элемент в строке содержит более 2 последовательных двойных кавычек.

Вот как форматируется файл: каждый элемент отделяется табуляцией. Если элемент содержит вкладку, он заключен в двойные кавычки. Если элемент содержит двойную кавычку, он удваивается. Но иногда элемент содержит 4 последовательных двойных кавычки, и приведенное выше регулярное выражение разделяет элемент на 2 разных.

Примеры:

item1ok "item" "2" "OK"

правильно разделен на 2 элемента: item1ok и item "2" ok (после обрезки ненужных кавычек), но:

item1oK "item" "" "2oK"

разбивается на 3 элемента: item1ok , item и "2ok (после повторной обрезки).

Кто-нибудь знает, как заставить регулярное выражение соответствовать этому случаю? Или есть другое решение просто разобрать TSV? (Я делаю это в C #).

Ответы [ 4 ]

7 голосов
/ 09 марта 2010

Вы можете использовать TextFieldParser . Технически это сборка VB, но вы можете использовать ее даже в C #, ссылаясь на сборку Microsoft.VisualBasic.FileIO.

Пример по ссылке выше даже показывает использование его в файле с разделителями табуляции.

6 голосов
/ 09 марта 2010

Вместо того, чтобы пытаться создать свой собственный анализатор файлов CSV / TSV (или с помощью String.Split), я бы посоветовал вам взглянуть на " Fast CSV Reader " или " FileHelpers library ».

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

1 голос
/ 09 марта 2010

Вместо использования RegEx, возможно, вы могли бы попробовать метод String.Split (Char []) метод.

0 голосов
/ 10 марта 2010

Я не знаю C #, но это должно сработать (на питоне)

txt = 'item1ok\t"item""2""oK"\titem1oK\t"item""""2oK"\tsomething else'
regex = '''
(?:                    # definition of a field
 "((?:[^"]|"")*)"   # either a double quoted field (allowing consecutive "")
 |                  # or
 ([^"]*)            # any character except a double quote
)                      # end of field
(?:$|\t)               # each field followed by a tab (except the last one)
'''
r = re.compile(regex, re.X)
# now find each match, and replace "" by " and remove trailing \t
# remove also the latest entry in the list (empty string)
columns = [t[0].replace('""', '"') if t[0] != '' else t[1].strip() for t in r.findall(txt)][:-1]
print columns
# prints: ['item1ok', 'item"2"oK', 'item1oK', 'item""2oK', 'something else']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...