J'ai le type de chaîne suivant
var string = "'string, duppi, du', 23, lala"
Je veux diviser la chaîne en un tableau sur chaque virgule, mais uniquement les virgules en dehors des guillemets simples.
Je n'arrive pas à trouver la bonne expression régulière pour le fractionnement ...
string.split(/,/)
me donnera
["'string", " duppi", " du'", " 23", " lala"]
mais le résultat devrait être:
["string, duppi, du", "23", "lala"]
Existe-t-il une solution multi-navigateurs?
javascript
regex
split
Hans
la source
la source
Réponses:
Avertissement
Mise à jour du 01/12/2014: La réponse ci-dessous ne fonctionne que pour un format très spécifique de CSV. Comme l'a correctement souligné DG dans les commentaires , cette solution ne correspond pas à la définition RFC 4180 du CSV et elle ne correspond pas non plus au format Microsoft Excel. Cette solution montre simplement comment analyser une ligne d'entrée CSV (non standard) qui contient un mélange de types de chaînes, où les chaînes peuvent contenir des guillemets et des virgules.
Une solution CSV non standard
Comme le souligne à juste titre Austincheney , vous devez vraiment analyser la chaîne du début à la fin si vous souhaitez gérer correctement les chaînes entre guillemets qui peuvent contenir des caractères échappés. De plus, l'OP ne définit pas clairement ce qu'est réellement une "chaîne CSV". Nous devons d'abord définir ce qui constitue une chaîne CSV valide et ses valeurs individuelles.
Donné: Définition de "chaîne CSV"
Pour les besoins de cette discussion, une "chaîne CSV" se compose de zéro ou plusieurs valeurs, où plusieurs valeurs sont séparées par une virgule. Chaque valeur peut être constituée de:
Règles / Notes:
'that\'s cool'
.\'
dans les valeurs entre guillemets simples.\"
dans les valeurs entre guillemets.Trouver:
Une fonction JavaScript qui convertit une chaîne CSV valide (telle que définie ci-dessus) en un tableau de valeurs de chaîne.
Solution:
Les expressions régulières utilisées par cette solution sont complexes. Et (IMHO) toutes les expressions régulières non triviales doivent être présentées en mode espacement libre avec beaucoup de commentaires et d'indentation. Malheureusement, JavaScript n'autorise pas le mode d'espacement libre. Ainsi, les expressions régulières implémentées par cette solution sont d'abord présentées dans la syntaxe des expressions régulières natives (exprimées en utilisant le pratique de Python
r'''...'''
la syntaxe de chaîne brute multi-lignes ).Voici d'abord une expression régulière qui valide qu'une chaîne CVS répond aux exigences ci-dessus:
Expression régulière pour valider une "chaîne CSV":
Si une chaîne correspond à l'expression régulière ci-dessus, alors cette chaîne est une chaîne CSV valide (selon les règles précédemment énoncées) et peut être analysée à l'aide de l'expression régulière suivante. L'expression régulière suivante est ensuite utilisée pour faire correspondre une valeur de la chaîne CSV. Il est appliqué à plusieurs reprises jusqu'à ce qu'il n'y ait plus de correspondance (et que toutes les valeurs aient été analysées).
Expression régulière pour analyser une valeur à partir d'une chaîne CSV valide:
Notez qu'il existe une valeur de cas particulier à laquelle cette expression régulière ne correspond pas - la toute dernière valeur lorsque cette valeur est vide. Cette "dernière valeur vide" spéciale est testé et géré par la fonction JavaScript qui suit.
Fonction JavaScript pour analyser la chaîne CSV:
Exemple d'entrée et de sortie:
Dans les exemples suivants, des accolades sont utilisées pour délimiter le
{result strings}
. (Ceci permet de visualiser les espaces de début / de fin et les chaînes de longueur nulle.)Notes complémentaires:
Cette solution nécessite que la chaîne CSV soit "valide". Par exemple, les valeurs sans guillemets peuvent ne pas contenir de barres obliques inverses ou de guillemets, par exemple, la chaîne CSV suivante n'est pas valide:
Ce n'est pas vraiment une limitation car toute sous-chaîne peut être représentée sous la forme d'une valeur entre guillemets simples ou doubles. Notez également que cette solution ne représente qu'une seule définition possible pour les «valeurs séparées par des virgules».
Modifier l'historique
la source
"field one", "field two", "a ""final"" field containing two double quote marks"
je n'ai pas testé la réponse de Trevor Dixon sur cette page, mais c'est une réponse qui répond à la définition RFC 4180 du CSV.Solution RFC 4180
Cela ne résout pas la chaîne de la question car son format n'est pas conforme à la RFC 4180; le codage acceptable échappe entre guillemets doubles. La solution ci-dessous fonctionne correctement avec les fichiers CSV d / l des feuilles de calcul Google.
MISE À JOUR (3/2017)
L'analyse d'une seule ligne serait erronée. Selon la RFC 4180, les champs peuvent contenir CRLF, ce qui provoquera la rupture du fichier CSV par tout lecteur de ligne. Voici une version mise à jour qui analyse la chaîne CSV:
ANCIENNE RÉPONSE
(Solution sur une seule ligne)
Et pour le plaisir, voici comment créer un CSV à partir du tableau:
la source
Grammaire PEG (.js) qui gère les exemples RFC 4180 à l' adresse http://en.wikipedia.org/wiki/Comma-separated_values :
Testez sur http://jsfiddle.net/knvzk/10 ou https://pegjs.org/online .
Téléchargez l'analyseur généré à l' adresse https://gist.github.com/3362830 .
la source
J'ai eu un cas d'utilisation très spécifique où je voulais copier des cellules de Google Sheets dans mon application Web. Les cellules peuvent inclure des guillemets et des caractères de nouvelle ligne. En utilisant le copier-coller, les cellules sont délimitées par des caractères de tabulation et les cellules avec des données impaires sont entre guillemets. J'ai essayé cette solution principale, l'article lié utilisant regexp et Jquery-CSV et CSVToArray. http://papaparse.com/ Est le seul qui a fonctionné hors de la boîte. Le copier-coller est transparent avec Google Sheets avec des options de détection automatique par défaut.
la source
J'ai aimé la réponse de FakeRainBrigand, mais elle contient quelques problèmes: il ne peut pas gérer les espaces entre un guillemet et une virgule, et ne prend pas en charge 2 virgules consécutives. J'ai essayé de modifier sa réponse, mais ma modification a été rejetée par des critiques qui ne comprenaient apparemment pas mon code. Voici ma version du code de FakeRainBrigand. Il y a aussi un violon: http://jsfiddle.net/xTezm/46/
la source
Les gens semblaient être contre RegEx pour cela. Pourquoi?
Voici le code. J'ai aussi fait un violon .
la source
Ajouter un de plus à la liste, car je trouve que tout ce qui précède n'est pas assez "KISS".
Celui-ci utilise regex pour trouver des virgules ou des retours à la ligne tout en sautant les éléments cités. J'espère que c'est quelque chose que les noobies peuvent lire par eux-mêmes. L'
splitFinder
expression rationnelle a trois fonctions (divisée par un|
):,
- trouve des virgules\r?\n
- trouve de nouvelles lignes, (potentiellement avec retour chariot si l'exportateur était gentil)"(\\"|[^"])*?"
- ignore tout ce qui est entouré de guillemets, car les virgules et les retours à la ligne n'ont pas d'importance. S'il y a un devis échappé\\"
dans l'élément cité, il sera capturé avant qu'un devis final puisse être trouvé.la source
Id, Name, Age 1, John Smith, 65 2, Jane Doe, 30
comment puis-je analyser en fonction des colonnes que je spécifie?[{Id: 1, Name: "John Smith", Age: 65}, {Id: 2, Name: "Jane Doe", Age: 30}]
Si vous pouvez faire en sorte que votre délimiteur de devis soit des guillemets, il s'agit d'un double de l' exemple de code JavaScript pour analyser les données CSV .
Vous pouvez d'abord traduire tous les guillemets simples en guillemets doubles:
... ou vous pouvez modifier l'expression régulière dans cette question pour reconnaître les guillemets simples au lieu des guillemets doubles:
Cependant, cela suppose un certain balisage qui n'est pas clair dans votre question. Veuillez préciser quelles peuvent être toutes les différentes possibilités de balisage, conformément à mon commentaire sur votre question.
la source
Ma réponse suppose que votre entrée reflète le code / contenu de sources Web où les guillemets simples et doubles sont entièrement interchangeables à condition qu'ils se produisent comme un ensemble de correspondance non échappé.
Vous ne pouvez pas utiliser regex pour cela. Vous devez en fait écrire un micro analyseur pour analyser la chaîne que vous souhaitez diviser. Dans l'intérêt de cette réponse, je vais appeler les parties entre guillemets de vos chaînes en tant que sous-chaînes. Vous devez spécifiquement marcher sur la chaîne. Prenons le cas suivant:
Dans ce cas, vous n'avez absolument aucune idée de l'endroit où une sous-chaîne commence ou se termine en analysant simplement l'entrée pour un modèle de caractère. Au lieu de cela, vous devez écrire une logique pour décider si un caractère guillemet est utilisé comme caractère guillemet, est lui-même sans guillemets et que le caractère guillemet ne suit pas un échappement.
Je ne vais pas écrire ce niveau de complexité de code pour vous, mais vous pouvez regarder quelque chose que j'ai récemment écrit et qui a le modèle dont vous avez besoin. Ce code n'a rien à voir avec des virgules, mais est par ailleurs un micro-analyseur suffisamment valide pour que vous puissiez suivre l'écriture de votre propre code. Regardez dans la fonction asifix de l'application suivante:
https://github.com/austincheney/Pretty-Diff/blob/master/fulljsmin.js
la source
Pour compléter cette réponse
Si vous avez besoin d'analyser les guillemets échappés avec un autre guillemet, exemple:
Vous pouvez utiliser
la source
"jjj "" kkk""","123"
Lors de la lecture du fichier CSV dans une chaîne, il contient des valeurs nulles entre les chaînes, essayez-le avec \ 0 ligne par ligne. Ça marche pour moi.
la source
J'ai également rencontré le même type de problème lorsque j'ai dû analyser un fichier CSV.
Le fichier contient une adresse de colonne qui contient le ','.
Après avoir analysé ce fichier CSV en JSON, j'obtiens un mappage incompatible des clés lors de la conversion en fichier JSON.
J'ai utilisé Node.js pour analyser le fichier et les bibliothèques comme baby parse et csvtojson .
Exemple de fichier -
Alors que j'analysais directement sans utiliser baby parse dans JSON, j'obtenais:
J'ai donc écrit du code qui supprime la virgule (,) avec tout autre délimiteur avec chaque champ:
La fonction retournée peut être passée dans la bibliothèque csvtojson et ainsi le résultat peut être utilisé.
Vous pouvez maintenant obtenir la sortie comme:
la source
Aucune expression régulière, lisible, et selon https://en.wikipedia.org/wiki/Comma-separated_values#Basic_rules :
la source
Selon cet article de blog , cette fonction devrait le faire:
Vous l'appelleriez ainsi:
Ce type de jsfiddle fonctionne, mais il semble que certains éléments aient des espaces devant eux.
la source
"'string, duppi, du', 23, lala"
["'string"," duppi"," du'"," 23"," lala"]
"'"
à'"'
et vice-versa.'"string, duppi, du", 23, lala'
donne:['"string',' duppi'.' du"',' 23',' lala']
Les expressions régulières à la rescousse! Ces quelques lignes de code gèrent les champs correctement entre guillemets avec des virgules incorporées, des guillemets et des retours à la ligne basés sur la norme RFC 4180.
Sauf indication contraire, vous n'avez pas besoin d'une machine à états finis. L'expression régulière gère correctement la RFC 4180 grâce à une analyse positive, une analyse négative et une anticipation positive.
Cloner / télécharger le code sur https://github.com/peterthoeny/parse-csv-js
la source
Mis à part l'excellente et complète réponse de ridgerunner , j'ai pensé à une solution de contournement très simple lorsque votre backend exécute PHP.
Ajouter ce fichier PHP back - end de votre domaine ( par exemple de:
csv.php
)Maintenant, ajoutez cette fonction à votre boîte à outils JavaScript (devrait être révisée un peu pour faire un crossbrowser je crois).
Cela vous coûtera un appel Ajax, mais au moins vous ne dupliquerez pas de code ni n'incluerez aucune bibliothèque externe.
Réf: http://php.net/manual/en/function.str-getcsv.php
la source
Vous pouvez utiliser papaparse.js comme l'exemple ci-dessous:
N'oubliez pas d'inclure papaparse.js dans le même dossier.
la source