我对正则表达式并不擅长,但我有以下内容,但我假设以下部分意味着寻找13 - 16位数,然后如果在此之后找到3 - 4位数则返回成功。问题是3-4位数字是可选的,它们也可以在13-16位数字之前,所以我想我想要结合正向前瞻/后视,负向前瞻/后视。这听起来很复杂,有更简单的方法吗?
(\d{13,16})[<"'].*?(?=[>"']\d{3,4}[<"'])[>"'](\d{3,4})[<"']
将匹配以下代码段中的ccnum和系列:
<CreditCard>
name="John Doe""
ccnum=""1111123412341231""
series="339"
exp="03/13">
</CreditCard>
但是,如果删除ccnum或系列,则它与任何内容都不匹配,并且该系列可以是可选的。系列也可以出现在ccnum之前或之后,所以如果我把系列属性放在ccnum属性之前,它也不会匹配任何东西。如果我在ccnum之前有一个系列作为单独的元素,例如或者如果我忽略一个系列元素,它也不匹配:
<CreditCard>
<series>234</series>
<ccnum>1235583839293838</ccnum>
</CreditCard>
我需要正则表达式匹配以下场景,但我不知道元素的确切名称,在这种情况下,我只称它们为ccnum和series。
以下是有效的方法:
<CreditCard>
<ccnum>1235583839293838</ccnum>
<series>123</series>
</CreditCard>
<CreditCard ccnum="1838383838383833">
<series>123</series>
</CreditCard>
<CreditCard ccnum="1838383838383833" series="139"
</CreditCard>
它也应匹配以下内容,但不会:
<CreditCard ccnum="1838383838383833"
</CreditCard>
<CreditCard series="139" ccnum="1838383838383833"
</CreditCard>
<CreditCard ccnum="1838383838383833"></CreditCard>
<CreditCard>
<series>123</series>
<ccnum>1235583839293838</ccnum>
</CreditCard>
<CreditCard>
<ccnum series="123">1235583839293838</ccnum>
</CreditCard>
现在,为了让这个工作,我使用3个单独的正则表达式:
1以匹配安全码之前的信用卡号。
1以匹配信用卡号码之前的安全码。
1只匹配信用卡号。
我尝试将表达式组合成一个或者,但最终总共有5个组(前2个表达式中有2个,最后一个中有1个)
答案 0 :(得分:0)
使用Parse方法将XML拉入XDocument可能要容易得多。然后,您可以使用XPath或其他方法查找该数据。
关于正则表达式:你的正则表达式让我理解复杂,但这就是你如何使某个块可选:“(thisisoptional)?”。
除非将两个订单手动包含在正则表达式中,否则您无法解释这两个不同的订单。因此,如果您希望能够匹配“ab”和“ba”(不同的顺序),则需要以下正则表达式:“((ab)|(ba))”。所以一切都是两次。您可以通过将“a”和“b”分解为每个字符串变量来减少这种恶意。
答案 1 :(得分:0)
您可以尝试递归遍历XML文档并抓取与ccnum
和series
的表达式匹配的每个属性和文本节点,并将它们附加到List<string> ccNumList
和List<string> seriesList
。如果ccnum
和series
在DOM树层次结构中的顺序相同,那么ccNumList[i] == seriesList[i]
。
执行递归树遍历的示例是here。
答案 2 :(得分:0)
(?<=[>\"'](\\d{3,4})[<\"'].{0,100})?[>\"'](\\d{13,16})[<\"'](?=.*[>\"'](\\d{3,4})[<\"'])?
这将创建三个捕获组,其中ccnum
始终位于第二组中,series
可以位于第一组,第三组或任何组中。
ccnum = match.Groups[2].Value;
series = match.Groups[1].Value + m.Groups[3].Value;