正则表达式在文件中查找信用卡号不起作用

Posted

技术标签:

【中文标题】正则表达式在文件中查找信用卡号不起作用【英文标题】:RegEx to find credit card number in documents does not work 【发布时间】:2011-01-15 04:14:47 【问题描述】:

我正在创建一个小型应用程序,它将打开一个 word 文档,扫描它以获取信用卡号(不同的模式),替换文本,保存并关闭文档。

我的代码很简单:

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): Find What 文本包含无效的模式匹配表达式”。

我认为这可能与我发送到 Word 的字符有关,因此我之前将 \d 替换为 [0-9]。但没有变化。如果我使用 [0-9]16 运行,它会将 1234567891012345 替换为我要使用的字符串。

有人可以帮我吗?我是否必须使用许多不同的正则表达式来搜索来管理文档,或者这可以使用一个简单的正则表达式来完成,就像我已经拥有的一样?

【问题讨论】:

我很好奇你会在扫描信用卡号码时获得多少帮助......(不是我的反对票) 让我这样说 - 我的客户有数千份文档和电子邮件,其中包含卡号。这是一个安全风险。所以我将不得不再次打开、搜索、删除和关闭。 重复***.com/questions/2235364/… 该死的——这是怎么发生的?我会关门的。 这比一棵 100 年的橡树还要阴暗。 【参考方案1】:

尝试\\b 而不是\b。否则,字符串解析器将尝试将 ascii 代码 007 (bell) 放入字符串中,而您将得不到匹配。

【讨论】:

恐怕没有多大帮助:(【参考方案2】:

你试过逃跑吗?:

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

如果这不起作用,您需要从一个简单的正则表达式(或者实际上只是一个纯文本单词)开始,验证它是否有效,然后分阶段构建正则表达式。

【讨论】:

我现在有 - 两者都有 @"\\b(?:[0-9][ -]*?)13,16\\b" 和 @"\b(?: [0-9][-]*?)13,16\b"。但同样的例外:( 至少你一路帮助我——分阶段构建它们。为此+1。谢谢!【参考方案3】:

以非常简单的方式做这件事给了我一些有用的东西:

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 等数字。如有必要,我会添加其他人。

【讨论】:

【参考方案4】:

我的猜测是 Word 有它自己的正则表达式风格。您是否尝试过在 Word 中打开文档并在“查找和替换”对话框中使用该正则表达式?

实际上,根据http://www.regexinference.com/documentation/Microsoft-Word-Wildcards-as-Regular-Expressions.html,Word 不支持非捕获括号,所以你将不得不想出一个不同的解决方案。

【讨论】:

【参考方案5】:

到目前为止,我们有以下最佳解决方案,它超越了单行。 这不是 ms 字,但你肯定能得到你想要的。

private const string _creditCardPatternMatchingExpression = @"(?m:-[*]\w2\d15,16)|(?m:CC\w2\d15,16)|(?m:\d15,16)|(\d4-\d4-\d4-\d4)|(\d4-\d6-\d5)";

        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;
    

【讨论】:

以上是关于正则表达式在文件中查找信用卡号不起作用的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式识别商店信用卡号

使用正则表达式验证信用卡号

使用正则表达式前瞻将信用卡号拆分为 4 块?

用于检测信用卡号的算法减少误报/负数

TextBox:为信用卡号插入空格?

如何在.net中屏蔽信用卡号的前6位和后4位