使用正则表达式从字符串中提取 ICCID

Posted

技术标签:

【中文标题】使用正则表达式从字符串中提取 ICCID【英文标题】:Extracting ICCID from a string using regex 【发布时间】:2016-09-23 12:37:42 【问题描述】:

我正在尝试返回并打印设备中 SIM 卡的 ICCID; SIM 卡来自不同的供应商,因此长度不同(19 位或 20 位)。因此,我正在寻找一个能够提取 ICCID 的正则表达式(以一种与直接围绕它的非单词字符无关的方式)。

鉴于 ICCID 被指定为以“89”开头的 19-20 位字符串,我只是选择了:

(89\d17,18)

这是我测试过的最成功的模式(还有一些因以下原因被拒绝的模式)。

在我从中提取它的字符串中,ICCID 后面紧跟一个回车符,然后是一个换行符,但是一些针对以 \r\n 甚至 \b 终止它的测试失败了工作(我正在使用的程序是基于 python 构建的内部程序,所以我怀疑这就是它用于正则表达式的程序)。此外,简单地使用(\d19,20) 最终提取了 20 位 ICCID 的最后 19 位(作为第三个也是最后一个有效匹配)。同样,我原则上排除了(\d19,20)?,因为我希望它会在找到前 19 位数字时完成。

所以我的问题是:我应该使用我选择的模式,还是有更好的表达式(不使用非单词字符来框定字符串)将返回最长的子字符串可变长度的数字字符串?

【问题讨论】:

这实际上取决于您要解析的文件/文本的格式。我建议你在像regex101.com/#python 这样的正则表达式测试器中“调整”你的表达式(使用“g”模式来模拟搜索) 我不明白为什么 \d19,20 只匹配 20 个字符中的 19 个 - 量词是贪婪的。 @WiktorStribiżew 我怀疑它匹配前 19 位数字,然后是所有 20 位数字,然后是最后 19 位数字。因为那是它得到的最后一场比赛,所以它就是返回的那一场。 好吧,如果您能提供更多详细信息、您尝试使用正则表达式的文本示例、您得到的精确匹配项、工具本身或其工作原理,我们可以提供更具体的帮助。跨度> 【参考方案1】:

如果幕后的引擎确实是 Python,并且您需要提取的值周围可能有任何非数字字符,请使用环视来限制值周围的上下文:

(?<!\d)89\d17,18(?!\d)
^^^^^^^         ^^^^^^

(?&lt;!\d) loobehind 要求匹配前没有数字,(?!\d) 负前瞻要求在该值之后没有数字。

见this regex demo

【讨论】:

【参考方案2】:

我会去

89\d17,18[^\d]

这应该首选 18 位数字,但 17 位也足够了。之后,将不再允许使用其他数字字符。

唯一的限制:ICCID 之后必须至少还有一个字符(根据您的描述应该没问题)。

请注意,任何带有“89”后跟 17 或 18 个数字字符的更长的数字序列也会匹配。

【讨论】:

对此有很多不同的解决方案。但这应该足够好。 请注意,Python 提供 \D[^\d] - 如果您想允许零个或多个字母,我会选择 \D*【参考方案3】:
(\d+)\D+ 

似乎很容易做到这一点。 (\d+ ) 将捕获 20 个数字。 \D+ 之后会匹配任何其他内容。

【讨论】:

以上是关于使用正则表达式从字符串中提取 ICCID的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中使用正则表达式从字符串中提取域名?

如何使用正则表达式从字符串中提取第 n 个 URL?

使用正则表达式从字符串中提取数字和符号

如何使用正则表达式从字符串中提取文件名[重复]

使用正则表达式从 mysql 列中提取子字符串

如何使用正则表达式从 C++ 字符串中提取字符串