2012-02-01 7 views
1

は私がそう考えると、16桁の番号の親ノードを検索し、そのセクション全体を返すために正規表現を使用したいが、どのように把握することはできません。正規表現を動作させるにはどうすればよいですか?

<Details> 
<CreditCard cardnum="123456789" ccv="123" exp="0212" cardType="1" name="joe" /> 
</Details> 

は私が返すようにしたいです

<CreditCard cardnum="123456789" ccv="123" exp="0212" cardType="1" name="joe" /> 

私はxmlを解析し、数字であるすべての属性を取得してそれを削除するつもりです。

私は.*(\d{13,16}).*を試しましたが、これはすべての文字を取得します。一度

、私は:私はint.TryParseを削除:

foreach(var x in elementsWithPossibleCCNumbers) 
{ 
//If attribute is number, replace value with empty string 
} 

注:

XElement element = XElement.Parse(xml); // XDocument.Load(xmlFile).Root 

IEnumerable<XElement> elementsWithPossibleCCNumbers = 
     element.Descendants() 
       .Where(d => d.Attributes() 
          .Where(a => a.Value.Length == 16) 
          .Count() == 1); 

私はどのように例えばelementsWithPossibleCCNumbersの各属性をループに把握することはできません今。

私はこれを行うことを決めた。

IEnumerable<XElement> elementsWithPossibleCCNumbers = 
     element.Descendants() 
       .Where(d => d.Attributes() 
          .Where(a => a.Value.Length >= 13 && a.Value.Length <= 16) 
          .Count() == 1).Select(x=>x); 


foreach(var x in elementsWithPossibleCCNumbers) 
{ 
    foreach(var a in x.Attributes()) 
    { 

    xml = xml.Replace(a.Value, new String('*',12)); 
    } 
} 

私が16桁の属性を持つ第二の要素を持っている場合は、それが唯一の属性値の一部を置き換えます。

+0

を伝えることができない、のろいです、彼らが適切に働く前に魔法を使う。 – Yuck

+2

なぜXMLを逆シリアル化しないのですか?または、LINQ to XMLを使用して、必要なXML要素を正確に取り戻すことができますか? –

+2

デシリアライズしたくない場合は、XPathを使用することもできます。 – seanzi

答えて

3

は、私は次のようなものをするでしょう。

<Details> 
<CreditCard cardnum="123456789" 
      ccv="123" 
      exp="0212" 
      cardType="1" 
      name="joe" /> 
</Details> 

不可知論者っぽいコード:

XElement element = XElement.Parse(xml); // XDocument.Load(xmlFile).Root 
int ccNumber; 

IEnumerable<XElement> elementsWithPossibleCCNumbers = 
     element.Descendants() 
       .Where(d => d.Attributes() 
          .Where(a => a.Value.Length == 16) 
          .Where(a => int.TryParse(a.Value, out ccNumber)) 
          .FirstOrDefault() != null); 

// Do not use ccNumber 
// Use elementsWithPossibleCCNumbers 

を。これは、属性の数を含むように拡張することができ...

IEnumerable<XElement> elementsWithPossibleCCNumbers = 
     element.Descendants() 
       .Where(d => d.Attributes() 
          .Where(a => a.Value.Length == 16) 
          .Where(a => int.TryParse(a.Value, out ccNumber)) 
          .FirstOrDefault() != null 
          && d.Attributes().Count() == 5); 

があるようなXMLを想定し

Regexを使用したり、XML要素名をハードコーディングしたりすることを含まない多数の可能性私は最後の手段としてRegexを使用する傾向があります。特に、私のためにすべてのデータを解析できる何かがある場合は特にそうです。1

elementsWithPossibleCCNumbers

更新は、長さ16桁であり、整数で1以上属性を含むXML要素です。それは正規表現に来るとき場合ということを、あなたは、私は通常、祈りに依存している...私は..

IEnumerable<XElement> elementsWithPossibleCCNumbers = 
     element.Descendants() 
       .Where(d => d.Attributes() 
          .Where(a => a.Value.Length == 16) 
          .Where(a => int.TryParse(a.Value, out ccNumber)) 
          .Count() == 1); 
          // Where only 1 attribute is 16 length and an int 

再びそれを拡張するためにそれを変更しますので、

IEnumerable<XAttribute> attributesWithPossibleCCNumbers = 
     element.Descendants() 
       .Where(d => d.Attributes() 
          .Where(a => a.Value.Length == 16) 
          .Where(a => int.TryParse(a.Value, out ccNumber)) 
          .Count() == 1) 
       .Select(e => e.Attributes() 
          .Where(a => a.Value.Length == 16) 
          .Where(a => int.TryParse(a.Value, out ccNumber)) 
          .First()); 
+0

私はあなたのものが私のものよりも好きです。 +1 –

+0

私はこれを撮影します。お待ち頂きまして、ありがとうございます。 – Xaisoft

+1

非常に良い:+1。もう少しXElementを調べなければなりません。あなたはこの種のことをとても簡単にすることができるとは気付かなかったのです! ;-) – Chris

1

Regexを使用してXMLを解析しないでください。それにはそれほど適していません。

代わりにXmlDocumentまたはXDocumentを使用することはどうですか?

+0

Regexは使いたくありませんが、XMLはさまざまです。この場合、CreditCardと呼ばれるかもしれませんが、PaymentInfo、CCInfo、CCDetailsなどと呼ばれることもあります。 – Xaisoft

+0

パフォーマンスのために 'XDocument'をお勧めします。 – Aphelion

+0

私は組み合わせを使うことができると思っていました。その属性の最初と子を取得し、XDocumentを使用して要素を解析します。 – Xaisoft

2

使用してみてください: < [^>] + [0-9] {16} [^>] +>

編集:これは、よりefficient- <かもしれない([^> 0-9] + )([0-9] {16})([^>] +)>

+0

ニース、これはうまくいきました。今私は属性を解析する必要があります。あなたは正規表現を説明してもらえますか? – Xaisoft

+0

Particuarly、式の '^'と '+'です。 – Xaisoft

+0

^は否定記号で、+はそれが複数回見つかったことを示します。これらは基本的な概念です。クレジットカード情報が平文で書かれているファイルを読んでいるのはなぜですか? –

3

私は試してみるために別の方法を書きました。正規表現はXML自体ではなく属性値を検証するようになりました。私はあなたがこのメソッドから何を返そうとしているのか分かりませんが、少なくともこれはRegex for XMLを使わないことから始めます。あなたのXMLが多くを変えることができますので

[Test] 
public void X() 
{ 
    const string xml = "<Details><CreditCard cardnum=\"123456789\" ccv=\"123\" exp=\"0212\" cardType=\"1\" name=\"joe\" /><donotfind>333</donotfind></Details>"; 

    var doc = new XmlDocument(); 
    doc.LoadXml(xml); 

    Console.WriteLine(doc.Name);; 

    foreach(XmlNode x in doc.ChildNodes) 
    { 
     ExploreNode(x); 
    } 
} 

void ExploreNode(XmlNode node) 
{ 
    Console.WriteLine(node.Name); 

    if (node.Attributes != null) 
    { 
     foreach (XmlAttribute attr in node.Attributes) 
     { 
      Console.WriteLine("\t{0} -> {1}", attr.Name, attr.Value); 

      if (attr.Value.Length == 16 && Regex.IsMatch(attr.Value, @"\d{16}")) 
      { 
       Console.WriteLine("\t\tCredit Card # found!"); 
      } 
     } 
    } 

    foreach (XmlNode child in node.ChildNodes) 
    { 
     ExploreNode(child); 
    } 
} 
+0

メソッドはいいですが、前にも述べたように、xml文字列は要素と属性が異なる名前と呼ばれるという意味で異なります。 – Xaisoft

+0

@Xaisoft:要素名や属性名を参照するものは何もありません。すべてが属性値からキーを離します。 –

+0

ああ、私は16の値を持つ属性をチェックしていますが、部分的に正規表現を使用しているのは何ですか? – Xaisoft

関連する問題