Niezły w teorii, okropny w praktyce
Przez CSV założę , że masz na myśli konwencję opisaną w RFC 4180 .
Dopasowanie podstawowych danych CSV jest banalne:
"data", "more data"
Uwaga: BTW, o wiele bardziej wydajne jest korzystanie z funkcji .split ('/ n'). Split ('”) dla bardzo prostych i dobrze zorganizowanych danych takich jak ta. Wyrażenia regularne działają jako NDFSM (niedeterministyczny skończony State Machine), która marnuje dużo czasu na cofanie się, gdy zaczniesz dodawać przypadki krawędzi, takie jak znaki ucieczki.
Oto na przykład najbardziej wyczerpujący ciąg pasujący do wyrażeń regularnych, jaki znalazłem:
re_valid = r"""
# Validate a CSV string having single, double or un-quoted values.
^ # Anchor to start of string.
\s* # Allow whitespace before value.
(?: # Group for value alternatives.
'[^'\\]*(?:\\[\S\s][^'\\]*)*' # Either Single quoted string,
| "[^"\\]*(?:\\[\S\s][^"\\]*)*" # or Double quoted string,
| [^,'"\s\\]*(?:\s+[^,'"\s\\]+)* # or Non-comma, non-quote stuff.
) # End group of value alternatives.
\s* # Allow whitespace after value.
(?: # Zero or more additional values
, # Values separated by a comma.
\s* # Allow whitespace before value.
(?: # Group for value alternatives.
'[^'\\]*(?:\\[\S\s][^'\\]*)*' # Either Single quoted string,
| "[^"\\]*(?:\\[\S\s][^"\\]*)*" # or Double quoted string,
| [^,'"\s\\]*(?:\s+[^,'"\s\\]+)* # or Non-comma, non-quote stuff.
) # End group of value alternatives.
\s* # Allow whitespace after value.
)* # Zero or more additional values
$ # Anchor to end of string.
"""
W rozsądny sposób obsługuje wartości pojedynczego i podwójnego cudzysłowu, ale nie nowe wartości w wartościach, cudzysłowy itp.
Źródło: Przepełnienie stosu - jak analizować ciąg za pomocą JavaScript
Staje się koszmarem po wprowadzeniu typowych skrzynek krawędziowych, takich jak ...
"such as ""escaped""","data"
"values that contain /n newline chars",""
"escaped, commas, like",",these"
"un-delimited data like", this
"","empty values"
"empty trailing values", // <- this is completely valid
// <- trailing newline, may or may not be included
Sam przypadek krawędzi nowej linii jako wartości jest wystarczający, aby złamać 99,9999% parserów opartych na RegEx znalezionych na wolności. Jedyną „rozsądną” alternatywą jest użycie dopasowania RegEx do podstawowego tokenizacji kontrolnej / niekontrolowanej (tj. Terminal vs nieterminalny) w połączeniu z maszyną stanu używaną do analizy wyższego poziomu.
Źródło: Doświadczenie znane również jako rozległy ból i cierpienie.
Jestem autorem jquery-CSV , jedynego na świecie parsera CSV opartego na javascript, w pełni zgodnego z RFC. Spędziłem miesiące zajmując się tym problemem, rozmawiając z wieloma inteligentnymi ludźmi i próbując tony, jeśli różne implementacje, w tym 3 pełne przeróbki silnika głównego parsera.
tl; dr - Morał tej historii, sam PCRE jest do bani, jeśli chodzi o parsowanie czegokolwiek poza najprostszymi i najściślejszymi zwykłymi gramatykami (tj. typ III). Mimo to jest przydatny do tokenizacji ciągów terminalowych i nieterminalnych.