C # - Diviser sur un tuyau avec un tuyau échappé dans les données?
J'ai un tuyau de fichier délimité que je souhaite partager (je suis en utilisant C#). Par exemple:
Cela|est|une|test
Cependant, certaines données peuvent contenir une pipe. Si il le fait, il sera par un antislash:
Cela|est|une|pip\|ed|test (c'est un pip|ed test)
Je me demandais si il y a une regexp ou d'une autre méthode pour diviser en dehors de cela sur la "pure" tuyaux (tuyaux qui n'ont pas de barre oblique inverse devant eux). Ma méthode actuelle est de remplacer les échappé à tuyaux avec un peu de texte, fendu sur les tubes, puis remplacer mon texte personnalisé avec un tuyau. Pas très élégant, je ne peux pas aider mais pense qu'il y a une meilleure façon. Merci pour toute aide.
source d'informationauteur Frijoles
Vous devez vous connecter pour publier un commentaire.
Suffit d'utiliser
String.IndexOf()
pour trouver le prochain tube. Si le caractère précédent n'est pas une barre oblique inverse, puis utilisezString.Substring()
pour extraire le mot. Sinon, vous pouvez utiliserString.IndexOfAny()
pour trouver l'occurrence suivante de la canalisation ou la barre oblique inverse.Je fais beaucoup de l'analyse de ce type, et c'est vraiment assez simple. Prenant mon approche, si elle est effectuée correctement, il aura aussi tendance à courir plus vite ainsi.
MODIFIER
En fait, peut-être quelque chose comme ça. Il serait intéressant de voir comment cela se compare au niveau des performances de une RegEx solution.
Cela devrais le faire:
L'expression régulière en gros dit: split sur les tuyaux qui ne sont pas précédés d'un caractère d'échappement. Je ne devrais pas prendre tout le crédit pour ce bien, j'ai juste détourné l'expression régulière à partir de ce post et simplifié.
MODIFIER
En termes de performances, par rapport au manuel d'analyse de la méthode fournie dans ce fil, j'ai trouvé que cette expression de la mise en œuvre est de 3 à 5 fois plus lent que Jonathon Bois est mise en œuvre à l'aide de la plus longue chaîne de test fournis par les OP.
Avec cela dit, si vous n'avez pas instancier ou ajouter des mots pour
List<string>
et de retour void au lieu de cela, Jon méthode arrive à environ 5 fois plus rapide que laRegex.Split()
méthode (0,01 ms vs 0.002 ms) pour des raisons purement de la séparation de la chaîne. Si vous ajoutez les frais généraux de gestion et de retourner unList<string>
il était d'environ 3,6 fois plus rapide (0,01 ms vs 0.00275 ms), en moyenne sur quelques jeux de un million d'itérations. Je n'ai pas utilisé la statique de la Regex.Split() pour ce test, j'ai plutôt créé une nouvelle Regex exemple avec l'expression ci-dessus en dehors de mon test de la boucle, puis a appelé sa méthode Split.Mise à JOUR
À l'aide de la statique de la Regex.Split() la fonction est en fait beaucoup plus vite que la réutilisation d'une instance de l'expression. Avec cette mise en œuvre, l'utilisation de regex n'est que d'environ 1,6 fois plus lent que Jon est mise en œuvre (0.0043 ms vs 0.00275 ms)
Les résultats étaient les mêmes à l'aide de l'une expression régulière étendue de la poste je lien.
Je suis tombé sur un scénario similaire, Pour moi, le nombre de tuyaux ont été fixé(pas de tuyaux avec des "\|") . C'est la façon dont j'ai géré.
Ici est une autre solution.
L'une des plus belle chose à propos de la programmation, est plusieurs manières de donner une solution au même problème:
Cory solution est assez bonne. Mais, si vous préférez ne pas travailler avec des Regex, alors vous pouvez simplement faire quelque chose de la recherche pour "\|" et son remplacement par un autre caractère, puis de faire votre split, puis le remplacer à nouveau avec le "\|".
Est une autre option est de faire la split, puis examiner l'ensemble des chaînes de caractères et si le dernier caractère est un \, puis joindre à la chaîne suivante.
Bien sûr, tout cela ignore ce qui se passe si vous avez besoin d'un échappé de la barre oblique inverse avant une pipe.. comme "\\|".
Dans l'ensemble, je me penche vers regex.
Franchement, je préfère utiliser FileHelpers parce que, même si ce n'est pas par des virgules delimeted, c'est fondamentalement la même chose. Et ils ont une grande histoire sur pourquoi vous ne devriez pas écrire ce genre de choses vous-même.
Vous pouvez le faire avec une regex. Une fois que vous décidez d'utiliser une barre oblique inverse comme votre caractère d'échappement, vous avez deux échapper cas tenir compte:
\|
Ces deux peut être fait dans le même regex. Échappé des barres obliques inverses seront toujours deux
\
personnages ensemble. Consécutifs, a échappé à barres obliques inverses sera toujours le même nombre de\
caractères. Si vous trouvez un numéro impair séquence de\
avant une pipe, cela signifie que vous avez échappé à plusieurs barres obliques inverses, suivie par une fuite de tuyau. Donc, vous voulez utiliser quelque chose comme ceci:Confusion, peut-être, mais il devrait fonctionner. Explication: