Skip to content

Instantly share code, notes, and snippets.

@abulte
Created October 3, 2018 15:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abulte/0c109fd09c98bd0be12b4a3a6d25b3a5 to your computer and use it in GitHub Desktop.
Save abulte/0c109fd09c98bd0be12b4a3a6d25b3a5 to your computer and use it in GitHub Desktop.
python-csv-fail-parsing-csv-doublequote
import re
def _guess_quote_and_delimiter(data, delimiters=None):
"""
Looks for text enclosed between two identical quotes
(the probable quotechar) which are preceded and followed
by the same character (the probable delimiter).
For example:
,'some text',
The quote with the most wins, same with the delimiter.
If there is no quotechar the delimiter can't be determined
this way.
"""
matches = []
for restr in (r'(?P<delim>[^\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?P=delim)', # ,".*?",
r'(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?P<delim>[^\w\n"\'])(?P<space> ?)', # ".*?",
r'(?P<delim>[^\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?:$|\n)', # ,".*?"
r'(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?:$|\n)'): # ".*?" (no delim, no space)
regexp = re.compile(restr, re.DOTALL | re.MULTILINE)
matches = regexp.findall(data)
if matches:
break
if not matches:
# (quotechar, doublequote, delimiter, skipinitialspace)
return ('', False, None, 0)
quotes = {}
delims = {}
spaces = 0
groupindex = regexp.groupindex
for m in matches:
n = groupindex['quote'] - 1
key = m[n]
if key:
quotes[key] = quotes.get(key, 0) + 1
try:
n = groupindex['delim'] - 1
key = m[n]
except KeyError:
continue
if key and (delimiters is None or key in delimiters):
delims[key] = delims.get(key, 0) + 1
try:
n = groupindex['space'] - 1
except KeyError:
continue
if m[n]:
spaces += 1
quotechar = max(quotes, key=quotes.get)
if delims:
delim = max(delims, key=delims.get)
skipinitialspace = delims[delim] == spaces
if delim == '\n': # most likely a file with a single column
delim = ''
else:
# there is *no* delimiter, it's a single column of quoted data
delim = ''
skipinitialspace = 0
# if we see an extra quote between delimiters, we've got a
# double quoted format
dq_regexp = re.compile(
r"((%(delim)s)|^)\W*%(quote)s[^%(delim)s\n]*%(quote)s[^%(delim)s\n]*%(quote)s\W*((%(delim)s)|$)" % \
{'delim':re.escape(delim), 'quote':quotechar}, re.MULTILINE)
if dq_regexp.search(data):
doublequote = True
else:
doublequote = False
return (quotechar, doublequote, delim, skipinitialspace)
data = """"Numéro de dossier","Administration","Type","Année","Séance","Objet","Thème et sous thème","Mots clés","Sens et motivation","Partie","Avis"
"20180364","Préfecture de la Haute-Vienne","Avis","2018","17/05/2018","communication des listes électorales en vue de l'organisation d'une cousinade.","Vie publique / Elections politiques","Liste électorale","Favorable","III","Madame X a saisi la commission d'accès aux documents administratifs, par un courrier enregistré à son secrétariat le 24 janvier 2018, du refus opposé par la préfecture de la Haute-Vienne à sa demande de communication des listes électorales du département.
Après avoir pris connaissance de la réponse de l'administration, la commission rappelle que la communication intégrale des listes électorales est régie par les dispositions particulières des articles L28 et R16 du code électoral, qui prévoient que ces listes sont communicables à tout candidat, parti ou groupement politique ainsi qu’à tout électeur, quel que soit le lieu où il est inscrit. L’article R16 de ce code précise que la communication à un électeur est subordonnée à la condition qu’il s’engage à ne pas en faire un usage purement commercial.
Dans sa décision du 2 décembre 2016 n° 388979 (au recueil), le Conseil d'Etat a jugé qu'afin d'éviter toute exploitation commerciale des données personnelles que comporte une liste électorale, le pouvoir réglementaire a subordonné l'exercice du droit d'accès à l'engagement, de la part du demandeur, de ne pas en faire un usage commercial. S'il existe, au vu des éléments dont elle dispose et nonobstant l'engagement pris par le demandeur, des raisons sérieuses de penser que l'usage des listes électorales risque de revêtir, en tout ou partie, un caractère commercial, l'autorité compétente peut rejeter la demande de communication de la ou des listes électorales dont elle est saisie. Il lui est loisible de solliciter du demandeur qu'il produise tout élément d'information de nature à lui permettre de s'assurer de la sincérité de son engagement de ne faire de la liste électorale qu'un usage conforme aux dispositions des articles L28 et R16 du code électoral. L'absence de réponse à une telle demande peut être prise en compte parmi d'autres éléments, par l'autorité compétente afin d'apprécier, sous le contrôle du juge, les suites qu'il convient de réserver à la demande dont elle est saisie.
La commission considère que le caractère purement commercial ou non de l’usage des listes s’apprécie au regard de l’objet de la réutilisation envisagée et de l’activité dans laquelle elle s’inscrit, la forme juridique retenue par le ré-utilisateur pour poursuivre cette activité et l'existence ou l'absence de ressources tirées de cet usage constituant à cet égard de simples indices. Doivent être regardées comme purement commerciales non seulement la commercialisation des données elles-mêmes, le cas échéant après retraitement, mais aussi leur utilisation dans le cadre d’une activité à but lucratif.
En l'espèce, la commission constate que Madame X certifie ne pas formuler sa demande dans un but commercial et mentionne l'objectif d'organiser une réunion de famille, dite ""cousinade"". La commission considère qu'en l'état, il n'existe aucun indice qui permettrait de penser que l'usage de ces listes électorales risquerait de revêtir, en tout ou partie, un caractère commercial, même si l'intéressée n'a pas souhaité communiquer le nom de la personne hébergée en EHPAD au profit de laquelle l'évènement est organisé. La commission émet donc un avis favorable à la demande, sous réserve que Madame X justifie de sa qualité d'électeur, quel que soit le lieu où elle est inscrite."
"""
# second item should be True
_guess_quote_and_delimiter(data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment