2015-10-23 1 views
1

VB2010: J'utilise RegEx pour désidentifier un bloc de texte et normaliser le texte. C'est-à-dire prendre des lignes de texte et dés-identifier le nom et le code de confirmation, puis normaliser le texte pour que les données s'alignent en colonnes. J'ai presque tout sauf la dernière partie où le code de confirmation est précédé d'un nombre variable de points et d'un identifiant de paquet de 2 à 4 caractères ou qui pourrait être manquant.Regex.Remplacer pour identifier/normaliser le texte colonnaire

'regex 
    Dim MyRegex As Regex = New Regex("(?<pre>^\s{0,2}(\d{1,3})\s(\d\d))(.+?)(?<post>\.\.(\d{1,3})\." + "(\w)\s((\w+?|\.\.)))(?<dots>\.+)(\w{6})", RegexOptions.IgnoreCase Or RegexOptions.Multiline) 

    'this is the replacement string 
    Dim replacement As String = "${pre}******/*****${post}${dots}******" 

    'replace the matched text in the InputText using the replacement pattern 
    Dim result As String = MyRegex.Replace(Input, replacement) 

Mon entrée de test avec un numéro, le nom, le numéro, le code de misc, id paquet, et le code de confirmation sur chaque ligne:

1 01SMITH/CH..1.A E2T......AAABBB 
    2 01MTC..1.A ..............CCCDDD 
    3 01GRIFFIN/JOHN..1.A E2...EEEFFF 
    4 01EL/MARY..1.Z E2XT......GGGHHH 
    5 02BUBBA/BILLY..2.A E2....IIIJJJ 
    6 01HILL/THOR..1.A E2WW....KKKLLL 

Ma sortie à ce jour:

1 01******/*****..1.A E2T......****** 
    2 01******/*****..1.A ..............****** 
    3 01******/*****..1.A E2...****** 
    4 01******/*****..1.Z E2XT......****** 
    5 02******/*****..2.A E2....****** 
    6 01******/*****..1.A E2WW....****** 

Je désidentifie le nom et le code de confirmation, mais l'identifiant du paquet de code avant que le code de confirmation ne soit variable, ce qui rejette ma sortie en colonne. Un peu coincé sur la partie finale de celui-ci, mais je suis vraiment proche. Je vise à le faire une seule regex mais ce n'est peut-être pas possible. Est-il possible de remplacer un remplacement de regex?

Mise à jour avec une solution:

'regex (added one more group for the package id so I can determine its length) 
    Dim MyRegex As Regex = New Regex("(?<pre>^\s{0,2}(\d{1,3})\s(\d\d))(.+?)(?<post>\.\.(\d{1,3})\.(\w)\s(?<pkid>(\w+?|\.\.)))(?<dots>\.+)(\w{6})", RegexOptions.IgnoreCase Or RegexOptions.Multiline) 

    'use the MatchEvaluator to examine each match and adjust accordingly 
    deid = MyRegex.Replace(deid, New MatchEvaluator(Function(m As Match) 
                 Return m.Groups("pre").Value & 
                  "******/*****" & 
                  m.Groups("post").Value & 
                  New String("."c, 5 - m.Groups("pkid").Value.Length) & 
                  "******" 
                End Function)) 

je lance que par les données de test et voici ce que je reçois:

-----Input------------------------------------------------ 
1 01SMITH/CH..1.A E2T......AAABBB 
2 01MTC..1.A ..............CCCDDD 
3 01GRIFFIN/JOHN..1.A E2...EEEFFF 
4 01EL/MARY..1.Z E2XT......GGGHHH 
5 02BUBBA/BILLY..2.A E2....IIIJJJ 
6 01HILL/THOR..1.A E2WW....KKKLLL 
-----Output----------------------------------------------- 
1 01******/*****..1.A E2T..****** 
2 01******/*****..1.A .....****** 
3 01******/*****..1.A E2...****** 
4 01******/*****..1.Z E2XT.****** 
5 02******/*****..2.A E2...****** 
6 01******/*****..1.A E2WW.****** 
---------------------------------------------------------- 
+0

Quelle est la sortie que vous voulez obtenir? –

+0

Je suppose que vous savez que c'est facile à faire sans regex? –

+0

Stribizhev la sortie comme indiqué, mais aligné. À l'heure actuelle, tout est aligné sauf le code de confirmation. Andrew Je sais que je peux le faire sans regex, mais les données ci-dessus font partie d'un document plus volumineux et j'espère juste remplacer cette partie. – sinDizzy

Répondre

1

Peut-être, il peut y avoir une meilleure façon, mais il est possible pour atteindre ce que vous voulez avec your regex et Regex.Replace using a MatchEvaluator.

evaluator
Type: System.Text.RegularExpressions.MatchEvaluator
Une méthode personnalisée qui examine chaque match et retourne soit la chaîne assortie d'origine ou d'une chaîne de remplacement.

Le point est d'obtenir la longueur du groupe 3 et du groupe 8, et répétez le * le même nombre de fois. Pour ajouter une barre oblique, nous pouvons trouver le milieu en divisant la longueur du groupe 3 en 2. StrDup est une fonction pratique qui "multiplie" la chaîne le nombre de fois spécifié.

Voici un code VB.NET:

Dim Input As String = "1 01SMITH/CH..1.A E2T......AAABBB" & Environment.NewLine & "2 01MTC..1.A ..............CCCDDD" & Environment.NewLine & "3 01GRIFFIN/JOHN..1.A E2...EEEFFF" & Environment.NewLine & "4 01EL/MARY..1.Z E2XT......GGGHHH" & Environment.NewLine & "5 02BUBBA/BILLY..2.A E2....IIIJJJ" & Environment.NewLine & "6 01HILL/THOR..1.A E2WW....KKKLLL" 
Dim MyRegex As Regex = New Regex("(?<pre>^\s{0,2}(\d{1,3})\s(\d\d))(.+?)(?<post>\.\.(\d{1,3})\." + "(\w)\s((\w+?|\.\.)))(?<dots>\.+)(\w{6})", RegexOptions.IgnoreCase Or RegexOptions.Multiline) 
Dim result As String = MyRegex.Replace(Input, New MatchEvaluator(Function(m As Match) 
            Return m.Groups("pre").Value & 
            StrDup(m.Groups(3).Value.Length, "*").Insert(m.Groups(3).Value.Length/2, "/") & 
            m.Groups("post").Value & 
            m.Groups("dots").Value & 
            StrDup(m.Groups(8).Value.Length, "*") 
           End Function)) 
Console.WriteLine(result) 

Résultat:

1 01****/****..1.A E2T......****** 
2 01**/*..1.A ..............****** 
3 01******/******..1.A E2...****** 
4 01****/***..1.Z E2XT......****** 
5 02******/*****..2.A E2....****** 
6 01****/*****..1.A E2WW....****** 
+0

Je suis assez sûr que l'intention est de remplacer n'importe quel nom par la chaîne fixe "******/*****" plutôt que de remplacer les caractères par des astérisques. –

+0

Andrew oui c'était mon intention originale mais avec ce peu d'aide je pense que ça va marcher. laissez-moi tester le code avec quelques modifications et ajouter à la demande d'origine. – sinDizzy

+1

stribizhev merci pour le conseil. Je ne pense pas avoir déjà utilisé le MatchEvaluator mais je l'ajouterai définitivement à ma boîte à outils. Basant la solution finale sur votre suggestion, je l'ai un peu ajusté pour ajuster les points entre l'identifiant du paquet et le code de confirmation. C'était la variable qui devait être modifiée et cela fonctionne. N'a même pas besoin du groupe "points". Code définitif dans l'op. – sinDizzy