我怎样才能用Regex实现这个目标?

时间:2012-01-26 21:22:02

标签: c# regex

我有以下xml代码段:

<CreditCard 
   name="John Doe" 
   ccnum="1234123412341234" 
   ccv="239" 
   exp="03/13">
</CreditCard>


<CreditCard>
   <name>John Doe</name>
   <ccnum>1234123412341234</ccnum>
   <ccv>239</ccv>
   <exp>03/13</exp>
</CreditCard>

上面的代码片段只是xml存储信用卡数据的众多方式中的两种,所以这是我的问题,我需要扫描一个xml字符串并找到一个我已经完成的16位数字,但之后我需要确定安全代码的位置,在这种情况下ccv我将假设在CreditCard元素中的3-4位数字或类似的东西,然后加密。我的初步想法是找到16位数字然后返回,直到我找到第一个开始元素并假设这是信用卡数据的开始然后前进并搜索3-4位数字,但我是不确定如何去做?

让我假设我坚持使用正则表达式:

首先我找到13 - 16位数字,所以在第一个例子中,我找到了:

1234123412341234,现在我想在那里扫描一个3-4位数字,这就是我被困住的地方。

代码:

//This encrypts 13-16 digit numbers, now I just need to encrypt the 3-4 digit security 
//code
foreach (Match cc in Regex.Matches(xml, @"\b\d{13,16}\b"))
 {

      Console.WriteLine(xml);
      Console.WriteLine(cc);
      xml = xml.Replace(cc.Value, "ENCRYPTED");
      Console.WriteLine(xml);

  }

3 个答案:

答案 0 :(得分:6)

不再是小马......

是否有一个特殊原因你不能只使用XML?如果没有,那么您可以使用XML

XmlDocument doc = new XmlDocument();
doc.LoadXml(myString);

foreach(XmlElement card in doc.GetElementsByTagName("CreditCard")) {
    // Use card.GetElementsByTagName("name")[0].InnerText, etc.
}

答案 1 :(得分:1)

我找到了这个正则表达式。

(\\d{13,16})[<\"'].*?(?=[>\"']\\d{3,4}[<\"'])[>\"'](\\d{3,4})[<\"'];

注意:我使用正则表达式,因为XML架构不是常规

我是根据以下规则写的。

  1. 信用卡号码是长度在13-16之间的序列号。因此\d{13,16}
  2. CCV编号是长度为3-4的序列号。因此\d{3,4}
  3. CCV`应始终出现在信用卡号码之后。在这两者之间必须至少有一个非数字字符。至少在大多数情况下。因此整个模式。
  4. 如果我的任何假设都错了,请告诉我。

    示例代码

    class Program
    {
        static void Main(string[] args)
        {
            string data = @"<CreditCard> 
                       name=""John Doe"" 
                       ccnum=""1111123412341234"" 
                       ccv=""111"" 
                       exp=""03/13"">
                    </CreditCard>
    
    
                    <CreditCard>
                       <name>John Doe</name>
                       <ccnum>2222123412341234</ccnum>
                       <ccv>222</ccv>
                       <exp>03/13</exp>
                    </CreditCard>
    
                    <ResCreditCard 
                        resCreditCardRPH=""1"" 
                        cardCode=""11724"" 
                                cardType=""Credit"" 
                                cardNumber=""3333111111111111"" 
                                cardHolderName=""s"" 
                                expirationDate=""2015-03-31""
                                seriesCode=""333"" />";
    
            string pattern = "(\\d{13,16})[<\"'].*?(?=[>\"']\\d{3,4}[<\"'])[>\"'](\\d{3,4})[<\"']";
            Regex re = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
    
            foreach (Match m in re.Matches(data))
                if (m.Success)
                    Console.WriteLine(
                        "Credit Card Number={0}, CCV={1}",
                        m.Groups[1].Value,
                        m.Groups[2].Value
                     );
    
        }
    }
    

    输出

    Credit Card Number=1111123412341234, CCV=111
    Credit Card Number=2222123412341234, CCV=222
    Credit Card Number=3333111111111111, CCV=333
    

答案 2 :(得分:0)

我不太明白这个问题。我假设至少你可以将每张信用卡分开,因为它将包含在CreditCard标签中。如果XML解析器不是一个选项,那么应该很容易想出一个表达式来匹配open和close标签。

在找到元素的开始/结束之后,我只会搜索ccnum并在其后搜索第一组连续数字,并对ccv执行相同的操作。