我怎样才能用Regex实现这一点

本文关键字:Regex 实现 这一点 | 更新日期: 2023-09-27 18:21:28

我有以下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位数字,但我不确定如何做到这一点?

让我假设我坚持Regex:

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

1234 1234 1234 1234,现在我想在里面扫描一个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);
  }

我怎样才能用Regex实现这一点

又不是小马了。。。

您不能仅仅使用XML有什么特别的原因吗?如果没有,那么您可以使用XML:

XmlDocument doc = new XmlDocument();
doc.LoadXml(myString);
foreach(XmlElement card in doc.GetElementsByTagName("CreditCard")) {
    // Use card.GetElementsByTagName("name")[0].InnerText, etc.
}

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

(''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`应始终出现在信用卡号之后。在这两者之间必须至少有一个非数字字符。至少在大多数情况下是这样。因此形成了整个模式

如果我的任何假设都是错误的,请告诉我。

样本代码

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

我不太明白这个问题。我假设,至少你可以将每张信用卡分开,因为它会被放在信用卡标签中。如果XML解析器不是一个选项,那么应该很容易找到一个匹配打开和关闭标记的表达式。

在找到元素的开始/结束后,我只需要在里面搜索ccnum并获取它之后的第一组连续数字,也可以对ccv做同样的操作。