Teoride güzel, pratikte korkunç
By CSV ben açıklandığı gibi kongre demek varsaymak gidiyorum RFC 4180 .
Temel CSV verilerini eşleştirmek önemsiz olsa da:
"data", "more data"
Not: BTW, bunun gibi çok basit ve iyi yapılandırılmış veriler için bir .split ('/ n'). Split ('"') işlevi kullanmak çok daha verimlidir. Normal İfadeler NDFSM (Deterministik Olmayan Sonlu Durum Makinesi), kaçış karakterleri gibi uç durumlar eklemeye başladığınızda çok fazla zaman geri izleme harcar.
Örneğin, bulduğum en kapsamlı düzenli ifade eşleme dizesi:
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.
"""
Tek ve çift tırnaklı değerleri makul bir şekilde işler, ancak değerlerde, kaçan tırnak işaretlerinde vb.
Kaynak: Yığın Taşması - Bir dizeyi JavaScript ile nasıl ayrıştırabilirim
Ortak uç durumlar tanıtıldığında kabus haline geliyor ...
"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
Yalnızca newline değeri olarak kenar durumu, vahşi doğada bulunan RegEx tabanlı ayrıştırıcıların% 99.9999'unu kırmak için yeterlidir. Tek 'makul' alternatif, daha yüksek seviyeli analiz için kullanılan bir durum makinesiyle eşleştirilmiş temel kontrol / kontrol dışı karakter (yani terminal vs terminal olmayan) belirteçleri için RegEx eşleşmesini kullanmaktır.
Kaynak: Başka türlü kapsamlı ağrı ve ıstırap olarak bilinen deneyim.
Dünyadaki javascript tabanlı, tam RFC uyumlu CSV ayrıştırıcısı olan jquery- CSV'nin yazarıyım. Ayları bu sorunla başa çıkmak, birçok akıllı insanla konuşmak ve çekirdek ayrıştırıcı motorunun 3 tam yeniden yazımı da dahil olmak üzere farklı uygulamalar varsa bir ton denemek için harcadım.
tl; dr - Hikayenin ahlakı, PCRE tek başına en basit ve katı düzenli (Ie Type-III) dilbilgisi dışında bir şeyi ayrıştırmak için berbat. Yine de, terminal ve terminal olmayan dizeleri tokenize etmek için yararlıdır.