RegEx найти номер кредитной карты в документах не работает - PullRequest
0 голосов
/ 10 февраля 2010

Я создаю небольшое приложение, которое откроет текстовый документ, отсканирует его на наличие номера кредитной карты (различные шаблоны), заменит текст, сохранит и закроет документ.

Мой код довольно прост:

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 );
                }
            }
        }
    }
}

Однако - при запуске я получаю исключение: «System.Runtime.InteropServices.COMException (0x800A15B8): текст« Найти что »содержит недопустимое выражение соответствия шаблона».

Я подумал, что это как-то связано с символами, которые я отправил в Word, поэтому я ранее обменял \ d на [0-9]. Но без изменений. Если я использую [0-9] {16}, он заменяет 1234567891012345 на строку, которую я хочу использовать.

Может кто-нибудь помочь мне здесь? Должен ли я искать по нескольким различным регулярным выражениям для управления документом, или это можно сделать с помощью одного простого регулярного выражения, подобного тому, которое у меня уже есть?

Ответы [ 5 ]

3 голосов
/ 10 февраля 2010

Попробуйте \\b вместо \b. В противном случае анализатор строк попытается ввести в строку код ascii 007 (колокольчик), и вы не получите совпадения.

1 голос
/ 10 февраля 2010

Очень простой способ дал мне то, что сработало:

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);
            }

Это не очень хорошая настройка, но эй - она ​​работает. Удаленные числа, такие как XXXXXXXXXXXXXXXX, XXXX XXXX XXXX XXXX и XXXX-XXXX-XXXX-XXXX. Я добавлю другие, если это необходимо.

1 голос
/ 10 февраля 2010

Вы пытались сбежать?:

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

Если это не сработает, вам нужно начать с простого Регулярного выражения (или просто с простого текстового слова), убедиться, что оно работает, а затем поэтапно создать RegEx.

0 голосов
/ 23 августа 2011

Наилучшим решением на данный момент является следующее, выходящее за рамки одной строки. Это не мс слово, но вы точно можете получить то, что хотите.

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;
    }
0 голосов
/ 10 февраля 2010

Полагаю, у Word есть свой вкус регулярных выражений. Вы пытались открыть документ в Word и использовать это регулярное выражение в диалоговом окне «Найти и заменить»?

На самом деле, согласно http://www.regexinference.com/documentation/Microsoft-Word-Wildcards-as-Regular-Expressions.html, Word не поддерживает скобки без захвата, поэтому вам придется придумать другое решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...