【问题标题】:C# Find/Replace Credit Cards In XML StringC# 在 XML 字符串中查找/替换信用卡
【发布时间】:2009-09-03 16:24:57
【问题描述】:

我从第三方收到相当长的 XML 字符串作为输出,并且 XML 中表示的某些字段可能包含信用卡号。我不提前知道节点/元素/属性名称。在 C# 中用占位符查找和替换卡号的最简单方法是什么?字符串函数?正则表达式?

编辑:我想我会做这样的事情:

Match m = Regex.Match(xml, ">[0-9]{16}<"); 
xml = xml.Replace(m.Value, ">FOOBAR<"); 

当然,如果字符串不存在,则检查异常。我认为这可能与校验和算法相结合,足以满足我的需求

感谢您的回复。

【问题讨论】:

  • 编辑:可以是任何信用卡。在传递它之前,我需要找到并替换 XML 字符串中的每个实例。谢谢。

标签: c# xml regex


【解决方案1】:

由于我们不知道它是什么样的信用卡(Master,Visa ..),所以有几个正则表达式:

这里:

* Visa: ^4[0-9]{12}(?:[0-9]{3})?$ All Visa card numbers start with a 4. New cards have 16 digits. Old cards have 13.
* MasterCard: ^5[1-5][0-9]{14}$ All MasterCard numbers start with the numbers 51 through 55. All have 16 digits.
* American Express: ^3[47][0-9]{13}$ American Express card numbers start with 34 or 37 and have 15 digits.
* Diners Club: ^3(?:0[0-5]|[68][0-9])[0-9]{11}$ Diners Club card numbers begin with 300 through 305, 36 or 38. All have 14 digits. There are Diners Club cards that begin with 5 and have 16 digits. These are a joint venture between Diners Club and MasterCard, and should be processed like a MasterCard.
* Discover: ^6(?:011|5[0-9]{2})[0-9]{12}$ Discover card numbers begin with 6011 or 65. All have 16 digits.
* JCB: ^(?:2131|1800|35\d{3})\d{11}$ JCB cards beginning with 2131 or 1800 have 15 digits. JCB cards beginning with 35 have 16 digits. 

要替换内容,您可以编写如下内容:

content.Replace(Regex.Match(content,regExpresion),something);

【讨论】:

  • 是的,我也在 Googleland 中发现了这一点。我不确定这是否真的回答了我的问题。
  • 当然有更好的方法,对我来说这种方法真的很幼稚。
  • 您认为非天真的更好的方法是什么?
【解决方案2】:

不要使用正则表达式来处理 XML。你的代码中会有你不知道的错误。

这是一种不需要任何关于 XML 文档结构的知识的方法:

foreach (XmlText t in myXmlDocument.SelectNodes("//text()")
{
   t.Value = myRegex.Replace(t.Value, replacement);
}

这不会发现像中间有 cmets 的文本节点这样的退化情况,但是如果您让 DOM 为您管理文本,所有编码、CDATA 等问题都会消失。

如果您不想在处理之前解析整个文档,您也可以对 XmlReader 执行相同的操作。

【讨论】:

    【解决方案3】:

    将 XML 视为字符串,您可以单步执行它,识别每个数字序列,如果该序列通过 Luhn checksum,则替换它。

    【讨论】:

    • 我不认为有一种简单的正则表达式方法可以实现校验和算法,但也许这与正则表达式结合可以解决问题。
    【解决方案4】:

    我不确定这是否可行。为了能够操作 XML 文档,您需要通过 DTD 或 Schema 了解结构。如果你环顾四周,我相信第三方应该有他们的 API。

    只有了解了 XML 结构,才能对其进行操作。

    【讨论】:

    • 我有他们的 API。我不一定要编写代码来专门扫描文档中的每个元素并进行替换。他们会定期添加新标签,因此我的代码需要不断修订。为了简单起见,我希望我可以将文档加载到一个字符串中并扫描它以查找类似于信用卡的任何内容,例如将其替换为 String.Empty。我只是在寻找有关完成此任务的最简单方法的建议。谢谢。
    【解决方案5】:

    类似于(\d[\w-]?){13,16}。这是一个相当宽松的正则表达式,但它解释了这样一个事实,即随机的人经常输入带有破折号和空格的信用卡。它接受并设置 13-16 个连续数字,在任何这样的数字对之间允许一个空格或破折号。

    【讨论】:

      【解决方案6】:

      请不要使用正则表达式来解析 XML。你会后悔的。他们处理entity references 吗?模式定义的实体呢? cmets中的标签?嵌套标签? CDATA 部分?

      将 XML 加载到解析器/DOM 中,找到您要查找的数据并将其替换(此时您可以应用正则表达式),然后将修改后的 XML 流出。

      【讨论】:

      • 他们处理实体引用吗?否 模式定义的实体呢? cmets中没有标签?没有嵌套标签?没有 CDATA 部分?不,它很普通,但没有友好的节点名称。只是一堆必须从 API 手册中解释的编号元素。我喜欢 XML 解析器的想法,但同样,它们会不时添加新标签,我必须不断调整我的代码或构建某种花哨的动态解析器​​。我真的在这里寻找又快又脏。
      • 如果您正在处理编号元素,我猜您正在处理 ANSI X12 EDI XML 或类似的东西。 API 应该为您提供有关哪些元素将包含信用卡数据的明确信息。为避免对解析代码进行持续维护,请将其设置为扫描这些元素。如果元素匹配,则对内容执行正则表达式搜索和替换。如果某个元素不匹配,则不要理会它。您唯一需要更改代码的情况是他们为信用卡数据添加了另一个元素。您可以将要扫描的元素列表移动到数据库或配置文件中。
      【解决方案7】:

      TrueWill:“我猜你正在处理 ANSI X12 EDI XML 或类似的东西。”

      不,它不是 ANSI X12。只是名字奇怪的元素。

      Robert Rossney:“这不会发现像中间有 cmets 的文本节点这样的退化情况,而是所有的编码、CDATA 等问题......”

      这些都不存在于 XML 中。对不起,我应该从一开始就澄清这一点。但这个建议对其他事情有帮助,谢谢。

      【讨论】:

        猜你喜欢
        • 2015-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-13
        • 2016-02-09
        • 1970-01-01
        • 2020-08-12
        • 2021-05-21
        相关资源
        最近更新 更多