1 votes

Portage de Python vers C#

J'essaie d'apprendre C#, venant d'un fond Python/PHP, et j'essaie de porter un script de Python pour commencer.

Le script lit un fichier texte ligne par ligne (environ 150K lignes), applique une liste de regex jusqu'à ce qu'il y ait une correspondance, obtient les résultats des groupes nommés et ajoute les valeurs comme propriétés d'une classe.

Voici à quoi ressemblent les données (chaque ligne commençant par 'No.' est le début d'un nouvel enregistrement) :

No.813177294  09/01/1987  150
Tit.INCAL INDÚSTRIA DE CALÇADOS LTDA (BR/PE)
\*PARÁGRAFO ÚNICO DO ART. 162 DA LPI.
Procurador: ROBERTO C. FREIRE

No.901699870  02/06/2009  LD6
\*Exigência Formal não respondida, Pedido de Registro de Marca considerado inexistente, de acordo com o Art. 157 da LPI

No.830009817  12/12/2008  003
Tit.BIOLAB SANUS FARMACÊUTICA LTDA. (BR/SP)
C.N.P.J./C.I.C./NºINPI : 49475833000106
Apres.: Nominativa ; Nat.: De Produto
Marca: ENXUG
NCL(9) 05 medicamentos para uso humano; preparações farmacêuticas; diuréticos, analgésicos;
anestésicos; anti-helmínticos; antibióticos; hormônios para uso medicinal.
Procurador: CRUZEIRO/NEWMARC PATENTES E MARCAS LTDA

Et à quoi ressemble la regex :

regexp = {
    # No.123456789  13/12/2008  560
    # No.123456789   13/12/2008  560
    # No.123456789 13/12/2008 560
    # No.123456789  560
    'number': re.compile(r'No.(?P<Number>[\d]{9}) +((?P<Date>[\d]{2}/[\d]{2}/[\d]{4}) +)?(?P<Code>.*)'),

    # NCL(7) 25 no no no no no ; no no no no no no; *nonono no non o nono
    # NCL(9) 25 no no no no no ; no no no no no no; *nonono no non o nono
    'ncl': re.compile(r'NCL\([\d]{1}\) (?P<Ncl>[\d]{2})( (?P<Especification>.*))?'),

    'doc': re.compile(r'C.N.P.J./C.I.C./NºINPI : (?P<Document>.*)'),
    'description': re.compile(r'\*(?P<Description>.*)'),

    ...
}

Maintenant mes questions :

1) Puis-je utiliser le même concept, en appliquant chacun d'un Dictionary<string, Regex> dans chaque ligne jusqu'à ce qu'il y ait une correspondance ?

2) Si je le fais, il y a un moyen d'obtenir un Dictionary<string, string> des résultats des groupes nommés ? (À ce stade, je peux tout traiter comme une chaîne de caractères).

3) Si je devais avoir une classe comme celle-ci...

class Record
{
    public string Number { get; set; }
    public string Date { get; set; }
    public string Code { get; set; }
    public string Ncl { get; set; }
    public string Especification { get; set; }
    public string Document { get; set; }
    public string Description { get; set; }
}

...il existe un moyen de définir les propriétés avec les valeurs des groupes nommés ?

4) Je ne comprends pas du tout ce qui se passe ici, essayer de coder dans un langage à typage statique tout en pensant dans un langage à typage dynamique ? Si c'est le cas, que puis-je faire ?

Désolé pour cette question un peu longue. J'ai vraiment essayé de la reprendre pour la rendre plus courte :-)

Merci d'avance.

3voto

Alex Martelli Points 330805

1., sûr

2. voir, par exemple, ici

3. oui, même concept de base que le 2.

4. Non, C# est suffisamment flexible pour vous permettre de porter votre architecture sur d'autres systèmes.

Pensez également à étudier ce livre comme la meilleure introduction à .NET pour les programmeurs Python ET vice versa (je suis partial, ayant été rédacteur technique et étant un ami de l'auteur, mais je pense que c'est objectivement défendable;-).

2voto

Gishu Points 59012
  1. Oui, vous pouvez.
  2. .Net prend en charge les groupes nommés. Ainsi, pour (?<first>group)(?'second'group) l'objet Match renvoyé permettra une recherche par nom comme ceci. Vous pouvez construire vous-même un dictionnaire à partir de cet objet ou passer directement l'objet Match.
    var match = Regex.Match("subject", "regex"); var matchedText = match.Groups("first")
    Voir Groupes nommés en .Net y Support Regex en .Net
  3. Je pense qu'écrire un Record Record.Parse(namedValueCollection) serait un moyen de le faire
  4. Vous écrivez du code... Vous apprenez. Je trouve la direction inverse un peu désorientante... Passer du dynamique au statique devrait être relativement plus facile... juste que vous pourriez avoir à écrire relativement plus de code pour certaines tâches de routine comme l'itération ou la carte ou la sélection, etc.

1voto

Preet Sangha Points 39414

Désolé, ce n'est pas une réponse spécifique, mais pourriez-vous utiliser IronPython pour convertir vos scripts pour qu'ils s'exécutent sous le CLR et passent ensuite à C# ?

1voto

Eran Betzalel Points 2158

Si vous voulez vraiment apprendre le C#, vous devriez demander uniquement des références et non des réponses complètes, comme par exemple celui-ci (classe RegEx) mais je suis sûr que vous pouvez trouver beaucoup plus d'informations en effectuant une recherche rapide sur Google.

1voto

Joel Coehoorn Points 190579

Ce que tu cherches semble faisable. Bien sûr, vous voudrez regarder System.Text.RegularExpressions et plus particulièrement le Regex type là.

De plus, j'aime beaucoup le modèle itérateur pour lire les lignes d'un fichier :

public static IEnumerable<string> ReadLines(string path)
{
    using(var sr = new StreamReader(path))
    {
       string line;
       while ( (line = sr.ReadLine()) != null)
       {
           yield return line;
       }
    }
}

Vous commencez avec ce code de base (que vous pouvez réutiliser presque partout) et l'appelez dans cette méthode :

public static IEnumerable<Record> ReadRecords(string path)
{
    IEnumerable<Regex> expresssions = new List<Regex>
    {
        new Regex( @"No.(?P<Number>[\d]{9}) +((?P<Date>[\d]{2}/[\d]{2}/[\d]{4}) +)?(?P<Code>.*)" ),
        new Regex( @"NCL\([\d]{1}\) (?P<Ncl>[\d]{2})( (?P<Especification>"), 
        new Regex( @"C.N.P.J./C.I.C./NºINPI : (?P<Document>.*)")
    };

    foreach ( MatchCollection matches 
        in ReadLines(path)
          .Select(s => expressions.First(e => e.IsMatch(s)).Matches(s)))
          .Where(m => m.Count > 0) 
    )                       
    {
        yield return Record.FromExpressionMatches(matches);
    }
}

Terminez en ajoutant une méthode d'usine statique à votre classe Record qui accepte un paramètre MatchCollection. La seule chose qui semble vous manquer ici est que vous vous attendez à frapper chacune des expressions une fois avant de compléter un seul enregistrement. Cela fonctionnera un peu différemment. Mais j'espère que cela vous donne suffisamment d'éléments pour vous permettre de vous lancer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X