2010-02-10 6 views
0

Je crée une petite application qui va ouvrir un document Word, le scanner pour un numéro de carte de crédit (différents modèles), remplacer le texte, enregistrer et fermer le document.RegEx pour trouver le numéro de carte de crédit dans les documents ne fonctionne pas

Mon code est assez simple:

using System; 
using System.IO; 
using System.Collections; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using Word = Microsoft.Office.Interop.Word; 

namespace ParseFilesAndRemoveRegExp 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      FileManagement m = new FileManagement(); 
      m.OpenSearchAndReplace(); 
     } 
    } 

    class FileManagement 
    { 
     Word.Application wordapp; 

     public FileManagement() 
     { 
      try 
      { 
       wordapp = new Word.Application(); 
      } 
      catch(Exception ex) 
      { 
       if (ex != null) 
       { 
        string s = ex.ToString(); 
       } 
      } 
     } 

     internal void OpenSearchAndReplace() 
     { 
      object nullobj = System.Reflection.Missing.Value; 
      try 
      { 
       object filename = @"c:\\temp\\document.docx"; 
       object replaceAll = Word.WdReplace.wdReplaceAll; 

       object matchWildCards = true; 
       object readOnly = false; 
       object isVisible = false; 

       Word.Document doc = wordapp.Documents.Open(ref filename, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, 
                  ref nullobj, ref nullobj, ref nullobj, ref nullobj, 
                  ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj); 
       doc.Activate(); 
       wordapp.Selection.Find.ClearFormatting(); 

       //wordapp.Selection.Find.Text = "[0-9]{16}"; 
       wordapp.Selection.Find.Text = "\b(?:[0-9][ -]*?){13,16}\b"; 
       wordapp.Selection.Find.Replacement.ClearFormatting(); 
       wordapp.Selection.Find.Replacement.Text = "---Cardnumber automatically removed---"; 

       wordapp.Selection.Find.Execute(ref nullobj, ref nullobj, ref nullobj, ref matchWildCards, 
            ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, 
            ref replaceAll, ref nullobj, ref nullobj, ref nullobj, ref nullobj); 
       doc.Save(); 
      } 
      catch(Exception ex) 
      { 
       string s = ex.ToString(); 
       if(wordapp != null) 
       { 
        //wordapp.Documents.Close(ref nullobj, ref nullobj, ref nullobj); 
        wordapp.Quit(ref nullobj, ref nullobj, ref nullobj); 
       } 
      } 
     } 
    } 
} 

Cependant - je reçois une exception quand je le lance: « System.Runtime.InteropServices.COMException (0x800A15B8): la zone Rechercher texte contient un motif Expression de correspondance qui n'est pas valide". Je pensais que cela pourrait avoir quelque chose à voir avec les caractères que j'ai envoyés à Word, donc j'ai précédemment échangé \ d avec [0-9]. Mais pas de changement. Si je cours avec [0-9] {16}, il remplace le 1234567891par la chaîne que je veux utiliser.

Quelqu'un peut-il m'aider ici? Dois-je effectuer une recherche avec un certain nombre de regex pour gérer un document, ou peut-il le faire avec une simple regex comme celle que j'ai déjà?

+1

Je suis curieux de savoir combien d'aide vous obtiendrez la numérisation des numéros de cartes de crédit ... (pas mon downvote BTW) –

+2

Que ma me exprimer ainsi - mon client a des milliers de documents et de courriels qui a numéros de carte en eux. Et c'est un risque de sécurité. Je vais donc devoir ouvrir, rechercher, retirer et refermer. – sonstabo

+2

dupliquer http://stackoverflow.com/questions/2235364/regex-to-find-credit-card-number-in-documents-does-not-work – ziya

Répondre

1

faire de la manière très simple m'a donné quelque chose qui a fonctionné:

for (int i = 0; i < 3; ++i) 
      { 
       if(i == 0) 
        wordapp.Selection.Find.Text = "[0-9]{16}"; 
       else if(i == 1) 
        wordapp.Selection.Find.Text = "[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}"; 
       else if(i == 2) 
        wordapp.Selection.Find.Text = "[0-9]{4} [0-9]{4} [0-9]{4} [0-9]{4}"; 

       wordapp.Selection.Find.Execute(ref nullobj, ref nullobj, ref nullobj, ref matchWildCards, 
               ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, 
               ref replaceAll, ref nullobj, ref nullobj, ref nullobj, ref nullobj); 
      } 

Il n'est pas une configuration très agréable, mais bon - ça marche. Les numéros supprimés comme XXXXXXXXXXXXXXXX, XXXX XXXX XXXX XXXX et XXXX-XXXX-XXXX-XXXX. J'ajouterai d'autres si nécessaire.

3

Essayez \\b au lieu de \b. Sinon, l'analyseur de chaînes essayera de mettre le code ASCII 007 (bell) dans la chaîne et vous n'obtiendrez pas de correspondance.

+0

N'a pas aidé beaucoup j'ai peur :( – sonstabo

1

Avez-vous essayé échapper ?:

wordapp.Selection.Find.Text = @"\b(?:[0-9][ -]*?){13,16}\b"; 

Si cela ne fonctionne pas, vous devez commencer par une expression régulière simple (ou, en fait, juste un mot de texte brut), vérifier que cela fonctionne et ensuite construire le RegEx par étapes.

+0

J'ai maintenant - à la fois avec @ "\\ b (?: [0-9] [-] *?) {13,16} \\ b" et @ "\ b (?: [0-9] [-] *?) {13,16} \ b ". Même exception :( – sonstabo

+0

Au moins vous m'avez aidé en cours de route - pour les construire par étapes. ça Merci! – sonstabo

0

Nous avons ce qui suit comme la meilleure solution à ce jour qui va au-delà de la ligne unique. Ce n'est pas un mot ms mais vous pouvez obtenir ce que vous voulez à coup sûr.

private const string _creditCardPatternMatchingExpression = @"(?m:-[*]\w{2}\d{15,16})|(?m:CC\w{2}\d{15,16})|(?m:\d{15,16})|(\d{4}-\d{4}-\d{4}-\d{4})|(\d{4}-\d{6}-\d{5})"; 

     public static string CleanCreditCardData(this String contentThatMayHaveCreditCardData) 
    { 
     string initiallyCleanedUpData = Regex.Replace(contentThatMayHaveCreditCardData, _creditCardPatternMatchingExpression, "CCXXXXXXXXXXXXXX"); 
     string completeSpaceEnterCleanedUpVersion = initiallyCleanedUpData.ToLower().Replace("\r\n", "").Replace("\n", "").Replace(" ", "").Replace("-", "").Replace("<br>", "").Replace("<br />", "").Replace("<br/>", "").Replace("&nbsp;", ""); 
     if (Regex.IsMatch(completeSpaceEnterCleanedUpVersion,_creditCardPatternMatchingExpression)) 
      return Regex.Replace(completeSpaceEnterCleanedUpVersion, _creditCardPatternMatchingExpression, "CCXXXXXXXXXXXXXX"); 

     return initiallyCleanedUpData; 
    } 
Questions connexes