이론적으로 훌륭하고 실제로 끔찍한
하여 CSV 나는에 설명 된대로 규칙을 의미하는 가정거야 RFC 4180 .
기본 CSV 데이터를 일치시키는 것은 쉽지 않습니다.
"data", "more data"
참고 : BTW, 매우 간단하고 체계적인 데이터에 .split ( '/ n'). split ( ' "') 함수를 사용하는 것이 훨씬 효율적입니다. 정규 표현식은 NDFSM (비 결정적 유한)으로 작동합니다. 이스케이프 문자와 같은 엣지 케이스를 추가하기 시작하면 많은 시간을 낭비하는 State Machine).
예를 들어 다음은 내가 찾은 가장 포괄적 인 정규식 일치 문자열입니다.
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.
"""
작은 따옴표와 큰 따옴표 값을 합리적으로 처리하지만 값의 줄 바꿈, 이스케이프 따옴표 등은 처리하지 않습니다.
출처 : Stack Overflow-JavaScript로 문자열을 구문 분석하는 방법
일반적인 엣지 케이스가 소개되면 악몽이됩니다 ...
"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
줄 바꿈 값 엣지 케이스만으로도 야생에서 발견되는 RegEx 기반 파서의 99.9999 %를 깨뜨리기에 충분합니다. 유일한 '합리적인'대안은 더 높은 수준의 분석에 사용되는 상태 기계와 쌍을 이루는 기본 제어 / 비 제어 문자 (예 : 터미널 대 비 터미널) 토큰 화에 RegEx 일치를 사용하는 것입니다.
출처 : 광범위한 고통과 고통으로 알려진 경험.
저는 세계에서 유일하게 자바 스크립트 기반의 완전한 RFC 호환 CSV 파서 인 jquery-CSV 의 저자입니다 . 나는이 문제를 해결하고 많은 지능적인 사람들과 이야기하고 핵심 파서 엔진을 3 번 완전히 다시 작성하는 것을 포함하여 다른 구현을 시도하는 데 몇 달을 보냈습니다.
tl; dr-이야기의 도덕, PCRE만으로는 가장 간단하고 엄격한 정규 (I-III) 문법 이외의 것을 파싱하는 데 짜증이납니다. 그럼에도 불구하고 터미널 및 비 터미널 문자열을 토큰 화하는 데 유용합니다.