首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在下面的示例中使用REGEX捕获重复出现的数字

如何在下面的示例中使用REGEX捕获重复出现的数字
EN

Stack Overflow用户
提问于 2020-04-08 21:43:54
回答 1查看 204关注 0票数 0

我们只是通过使用REGEX来使用简单的JavaScript .match(),我在匹配下面的REGEX pattern时遇到了一个问题。

在扫描下面的二维码之后,我尝试通过使用下面的REGEX来匹配序列号682321973

(?:(?:(?:[a-zA-Z0-9-])|(?:\u001d))*21([a-zA-Z0-9-]{1,15})\u001d.*$)|(?:S?([a-zA-Z0-9-]{1,18}))

之所以使用这个大的正则表达式,是因为在下图(21) 682321973中,SERIAL数字从(21)开始

因此,我们将忽略或不捕获(21)之前的数字或字母部分,一旦它与(21)匹配,我们将捕获剩余的数字,即682321973

但问题是下面的正则表达式不匹配,因为序列号682321973中重复出现了数字21,结果是973

但奇怪的是在序列号中,如果有一个22,即682322973而不是682321973,那么我们会得到正确的结果,即682322973

当我们扫描下面的二维码时

我们得到的文本是:"\u001d010405686902130021682321973\u001d24011020250\u001d422276"(不带引号)

我得到了序列号682321973的错误结果的代码片段注意:在下面的结果中,我们将索引1作为结果

代码语言:javascript
复制
const string = "\u001d010405686902130021682321973\u001d24011020250\u001d422276";
const regex = "(?:(?:(?:[a-zA-Z0-9-])|(?:\u001d))*21([a-zA-Z0-9-]{1,15})\u001d.*$)|(?:S?([a-zA-Z0-9-]{1,18}))";
const result = string.match(regex);

console.log(result);
// expected output: Array ["12344", "682321973"]

我得到序列号682322973的正确结果的代码片段

代码语言:javascript
复制
const string = "\u001d010405686902130021682322973\u001d24011020250\u001d422276";
    const regex = "(?:(?:(?:[a-zA-Z0-9-])|(?:\u001d))*21([a-zA-Z0-9-]{1,15})\u001d.*$)|(?:S?([a-zA-Z0-9-]{1,18}))";
    const result = string.match(regex);

    console.log(result);
    // expected output: Array ["12344", "682322973"]

所以有没有人能帮助我,如果这个数字再次出现在序列号682321973中,我需要这个来捕获682321973,而不仅仅是973

下面再附上一个供参考,只是为了显示序列号总是以(21)开头

EN

回答 1

Stack Overflow用户

发布于 2020-04-09 03:10:15

字符串

代码语言:javascript
复制
\u001d010405686902130021682321973\u001d24011020250\u001d422276

看起来有3个部分:

代码语言:javascript
复制
\u001d010405686902130021682321973
\u001d24011020250
\u001d422276

在这种情况下具有不同的长度。

这里,序列号包含在其中的第一个中(尽管从数据中看不出这一点)。可以将该字符串视为具有四个部分,可以通过三种可能的方式获得它们:

代码语言:javascript
复制
\u001d 01040568690 21 30021682321973
\u001d 0104056869021300 21 682321973
\u001d 0104056869021300216823 21 973

关联的序列号为30021682321973682321973873。尽管我们被告知682321973在这里是实际的序列号,因为序列号有1到18位数字,但所有这些数字都可能给出正确的值。

如果这些序列号中的任何一个是正确的,确定哪个是正确的唯一方法是在第二组数字中:

代码语言:javascript
复制
01040568690             (11 digits)
0104056869021300        (16 digits)
0104056869021300216823  (22 digits)

如果该组总是包含16位数字(就像在给出的两个示例中一样),我们可以使用正则表达式提取序列号

代码语言:javascript
复制
(?<=\\u\d{3}d\d{16}21)\d+(?=\\u\d{3}d)

Demo

Javascript的regex引擎不能识别Unicode字符。因此,\u001d被视为反斜杠,后跟字母u,再后跟数字001,再后跟字母d

正则表达式引擎执行以下操作。

代码语言:javascript
复制
(?<=      # begin positive lookbehind
  \\      # match '\'
  u       # match 'u'
  \d{3}   # match 3 digits (or replace with '001' if appropriate)
  d       # match 'd'
  \d{16}  # match 16 digits
  21      # match '21'
)         # end positive lookbehind  
\d+       # match 1+ digits (serial number) 
(?=       # begin positive lookahead
  \\      # match '\'
  u       # match 'u'
  \d{3}   # match 3 digits (or replace with '001' if appropriate)
  d       # match 'd'
)         # end positive lookahead

如果在\u001d和紧接序列号之前的21之间的字符串部分并不总是16位数字,那么唯一能够可靠地提取序列号的方法就是将字符串的这一部分分解成其组成部分,但是我们还没有被告知这些组成部分是什么。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61102152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档