String Replace avec condition

edwinzap
Messages postés
159
Date d'inscription
samedi 29 septembre 2012
Dernière intervention
21 juin 2016
- 5 févr. 2016 à 20:46 - Dernière réponse : Whismeril
Messages postés
12222
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 novembre 2018
- 11 févr. 2016 à 07:04
Bonjour,
La question est en fait très simple mais je trouve pas de solution.

Je souhaite transformer une chaine de caractère tel que "test, test" en "test.test".

En gros, si la virgule se trouve entre deux guillemets, je souhaite changer cette virgule en un point !

Pour la regex, j'ai trouvé ceci \"[A-Z a-z 0-9]+,[A-z a-z 0-9]+\" mais je ne trouve pas de solution pour remplacer juste la virgule !

Merci
Afficher la suite 

Votre réponse

23 réponses

Meilleure réponse
Whismeril
Messages postés
12222
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 novembre 2018
- 6 févr. 2016 à 07:10
1
Merci
Sur l'exemple de dot net perls, assez bas dans la page il montre une solutions avec un délégué. C'est ça qu'il faut faire.

Merci Whismeril 1

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 94 internautes ce mois-ci

edwinzap
Messages postés
159
Date d'inscription
samedi 29 septembre 2012
Dernière intervention
21 juin 2016
- 6 févr. 2016 à 08:24
Merci bcp !!!
edwinzap
Messages postés
159
Date d'inscription
samedi 29 septembre 2012
Dernière intervention
21 juin 2016
- 6 févr. 2016 à 08:26
Voilà la solution si jamais:
public static string ComaToDot(string s)
{
return Regex.Replace(s, "\".*,.*\"", delegate (Match match)
{
string v = match.ToString();
Printer.Print(v);
return v.Replace(',','.');
});
}
Whismeril
Messages postés
12222
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 novembre 2018
- 6 févr. 2016 à 11:24
Marque le sujet résolu.
edwinzap
Messages postés
159
Date d'inscription
samedi 29 septembre 2012
Dernière intervention
21 juin 2016
> Whismeril
Messages postés
12222
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 novembre 2018
- 6 févr. 2016 à 13:28
En réalité, le sujet est résolu, mais je pense pas avoir posé la bonne question de départ car mon problème est autre. Mon réel problème est que je lis un fichier csv avec séparateur la virgule. Malheureusement, dans des champs Commentaires, certaines personnes ont également placé des virgules mais le contenu de ces champs sont entre guillemets.
Comment faire dès lors pour split uniquement qd la virgule ne se trouve pas entre guillemet ? (Utiliser regex.split mais avec quelle regex? une regex conditionnelle ?)
Merci
Whismeril
Messages postés
12222
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 novembre 2018
> edwinzap
Messages postés
159
Date d'inscription
samedi 29 septembre 2012
Dernière intervention
21 juin 2016
- 6 févr. 2016 à 18:59
Ça mériterais l'ouverture d'un autre sujet.
En général un csv c'est assez figé, toujours les mêmes colonnes dans le même ordre, si c'est le cas, il suffit de faire la différence entre le nombre de données attendues après le split et ceux obtenus, tu "rejoin" celles en trop.
Commenter la réponse de Whismeril
Whismeril
Messages postés
12222
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 novembre 2018
- 5 févr. 2016 à 22:24
0
Merci
Bonsoir, il faut faire le replace de la Regex, pas celui de string.

http://www.dotnetperls.com/regex-replace
https://msdn.microsoft.com/fr-fr/library/ewy2t5e0(v=vs.110).aspx
edwinzap
Messages postés
159
Date d'inscription
samedi 29 septembre 2012
Dernière intervention
21 juin 2016
- 6 févr. 2016 à 00:58
Oui, je m'étais renseigné à ce niveau. Mais je n'arrive tjrs pas.
Voici ce que j'ai fais
Regex reg = new Regex("\".*,.*\"");
string a = "lala\"test, ceci est un test\" lala";
a= reg.Replace(a, "\".*[a].*\"");


La regex est juste mais le Replace incorrecte. Je le sais mais ne sais pas comment faire autrement...
edwinzap
Messages postés
159
Date d'inscription
samedi 29 septembre 2012
Dernière intervention
21 juin 2016
- 6 févr. 2016 à 01:10
J'ai finalement trouvé ceci, mais je ne crois pas que ça soit la meilleure façon (d'autant que ce test ne fonctionne uniquement s'il y a qu'un seul match)
Regex reg = new Regex("\".*,.*\"");
string a = "lala\"test, ceci est un test\" lala";
MatchCollection mc = reg.Matches(a);
string b = mc[0].ToString();
b = b.Replace(',', '.');
a = reg.Replace(a, b);
Commenter la réponse de Whismeril
Whismeril
Messages postés
12222
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 novembre 2018
- 10 févr. 2016 à 14:23
0
Merci
Bonjour

en tenant compte de ceci

Oui ça fonctionne mais je ne suis pas vraiment satisfait. Juste pour pouvoir splitter correctement, je dois changer les virgules en un autre caractère puis faire le chemin inverse après avoir splitter. Ça me semble un peu ridicule mais c'est la seule solution que j'ai trouvée pour l'instant (grâce à ton aide)


et de la discussion que tu as ouvert ce matin sur les regex.

As tu lu ce message?
http://codes-sources.commentcamarche.net/forum/affich-10060139-string-replace-avec-condition#9

Une autre option est de faire une regex sur la ligne entière, avec des groupes pour ne sortir que ce qui t'interresse. Pour pourvoir te proposer quelque chose, il faut un exemple de ligne (tant qu'à faire celle qui pose le plus de problème)


Whismeril
Messages postés
12222
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 novembre 2018
> Whismeril
Messages postés
12222
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 novembre 2018
- 10 févr. 2016 à 19:43
(,?"([^"]+(\r\n)*)+",?)|,

là je n'ai plus les vides mais toujours les doublons
Whismeril
Messages postés
12222
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 novembre 2018
> Whismeril
Messages postés
12222
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 novembre 2018
- 10 févr. 2016 à 20:24
bon, je tiens le bon bout,
(?(,"([^"]+(\r\n)*)+"),"([^"]+(\r\n)*)+",?|,)

me retourne les doublons sans les " en début et fin, donc il suffit de faire un Distinct sur le résultat.
Whismeril
Messages postés
12222
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 novembre 2018
- 10 févr. 2016 à 20:39
Et donc, avec en entrée une "ligne", puisque tu as dit savoir les spliter.
        public static string[] ChargeCSV(string Ligne)
        {
            return Regex.Split(Ligne, "(?(,\"([^\"]+(\\r\\n)*)+\"),\"([^\"]+(\\r\\n)*)+\",?|,)").Distinct().ToArray();           
        }
edwinzap
Messages postés
159
Date d'inscription
samedi 29 septembre 2012
Dernière intervention
21 juin 2016
- 10 févr. 2016 à 23:24
Merci beaucoup ça fonctionne parfaitement pour la première ligne mais le Distinct n'est pas la solution. Si pour un enregistrement j'ai plusieurs champ vide, il ne m'en retourne qu'un seul ! Ce qui fait que j'ai plus d'entête de colonne que de données par utilisateur !!!

En fait pq la regex retourne deux fois le même champ ?

(Je vais essayer de comprendre demain ce que fais exactement la regex que vous me proposé)
Whismeril
Messages postés
12222
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 novembre 2018
- 11 févr. 2016 à 07:04
Ça retourne les données en double parce qu'elle trouve à la fois une virgule et un bloc compris entre "", je n'ai pas trouvé comment faire un ou exclusif.
Ce que tu peux faire, c'est extraire la partie non null ou vide du résultat, faire le distinct dessus est remettre la partie null.

Nouvelle "ligne"
Sor,,"Jean,Edouard",01/01/2000,,"houlà y'a plein, plein de choses à dire, et
sur plusieurs lignes, ben oui
il faut bien, hein?"


J'ajoute une classe, qui permet d'extraire le texte avec son index d'origine et une extension qui permet de faire un distinct sur une propriété particulière

 
    /// <summary>
    /// Trouvé sur http://stackoverflow.com/questions/489258/linqs-distinct-on-a-particular-property
    /// </summary>
   static class Extension
    {

        public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            HashSet<TKey> seenKeys = new HashSet<TKey>();
            foreach (TSource element in source)
            {
                if (seenKeys.Add(keySelector(element)))
                {
                    yield return element;
                }
            }
        }
    }



public class TexteIndexe
    {
        public string Texte { get; set; }
        public int Index { get; set; }

        public static string[] ChargeCSV(string Ligne)
        {
            IEnumerable<string> split = Regex.Split(Ligne, "(?(,\"([^\"]+(\\r\\n)*)+\"),\"([^\"]+(\\r\\n)*)+\",?|,)");
            IEnumerable<TexteIndexe> splitIndexe = split.Select((t, i) => new TexteIndexe { Texte = t, Index = i });
            IEnumerable<TexteIndexe> texteSansDoublonEtPasVide = splitIndexe.Where(x => !string.IsNullOrWhiteSpace(x.Texte)).DistinctBy(x => x.Texte);
            IEnumerable<TexteIndexe> texteVide = splitIndexe.Where(x => string.IsNullOrWhiteSpace(x.Texte));
            string[] resultat = texteSansDoublonEtPasVide.Concat(texteVide).OrderBy(x => x.Index).Select(x => x.Texte).ToArray();
            return resultat;
        }


    }
Commenter la réponse de Whismeril

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.