不固定长度的字符串匹配正则表达式

3
我有这样的字符串
01084700069811461719010010285322921DA192089940088
01084700088763891719050010BM2120

这些字符串是数据矩阵字符串,我需要按照以下方式拆分字符串。
0108470006981146 17190100 102853229 21DA192089940088

0108470008876389 17190500 10BM2120

每个块都以固定的代码开头,后面跟着数字或字符。
  • 01 + 14位数字
  • 17 + 6位数字
  • 10 + 1到20个字符
  • 21 + 1到20个字符
我尝试使用正则表达式来实现这一点,对于前两个块,长度是固定的,因此没有问题。但是第三个(和/或第四个)块会有问题。
我创建了这个正则表达式:
/^(01\d{14})(?:(17\d{6}))*(?:(10\w*))*(?:(21\w*))*$/

这个字符串是正确的

01084700088763891719050010BM2120

Group 1. 0108470008876389 (ok)

Group 2. 17190500 (ok)

Group 3. 10BM2120 (ok)

但对于另一个字符串

01084700069811461719010010285322921DA192089940088

正则表达式匹配
Group 1. 0108470006981146 (ok)

Group 2. 17190100 (ok)

Group 3. 10285322921DA192089940088 (no)

我无法创建一个能够正确匹配第三个和第四个块的正则表达式,因为它们的字符数量没有固定长度,并且第三个块中可能会有字符串“21”,这也是下一个块的起始代码。

可以创建一个能够正确匹配字符串所有部分的正则表达式。

感谢大家。


1
如果这些块是连续的,并且bcd可以是可选的,请尝试使用^(01\d{14})(17\d{6})?(10\w{1,20})?(21\w{1,20})?$ - Wiktor Stribiżew
第三个和第四个块以"10"和"21"开头,并且在正则表达式中通过*(?:(10\w*))(?:(21\w))*部分进行匹配。 第三个块以"10"开头,可以包含数字21,但是21也是第四个块的起始代码。两个块都没有固定长度。 - AngelPoyel
1
请看 https://regex101.com/r/0p9Uz5/1。这符合你想要实现的吗? - Wiktor Stribiżew
1
不错的一击。似乎运行良好!:D 谢谢,你救了我的一天。 - AngelPoyel
为什么 0108470008876389 17190500 10BM 2120 不是有效的? - Redu
2个回答

1

你可以使用

^(01\d{14})(17\d{6})?(10\w{1,20})?(21\w{1,20})?$

查看正则表达式演示

请注意,如果您打算对捕获组进行量化,则无需使用非捕获组将其包装起来,可以直接量化捕获组。

此外,要使组变为可选项,只需要使用?量词即可,因为*匹配0个或多个出现次数。

模式详细信息

  • ^ - 字符串的开头
  • (01\d{14}) - 第1组:01和24个数字
  • (17\d{6})? - 第2组(可选):17和6个数字
  • (10\w{1,20})? - 第3组(可选):10和1至20个字母数字字符
  • (21\w{1,20})? - 第4组(可选):21和1至20个字母数字字符
  • $ - 字符串的结尾。
请注意,如果只匹配字母数字字符,您需要将\w替换为[^\W_],因为\w也会匹配_

我喜欢正则表达式,但它们也非常危险 :D。你有掌握正则表达式的资源吗? - AngelPoyel
1
@AngelPoyel 这种正则表达式的知识并不高级,你可以在http://regexone.com学习。从`\w`中减去`_`有点更加“隐藏”,你可以在SO上学习。 - Wiktor Stribiżew

0

var inputValue = "01084700088763891719050010BM2120";

var regexpr = /(01\d{14})(17\d{6})(10[A-Za-z0-9]{1,20})(21[A-Za-z0-9]{1,20})/;

inputValue.replace(regexpr, "$1 $2 $3 $4");

输出结果为:

"0108470008876389 17190500 10BM 2120"

var inputValue = "01084700069811461719010010285322921DA192089940088";

var regexpr = /(01\d{14})(17\d{6})(10[A-Za-z0-9]{1,20})(21[A-Za-z0-9]{1,20})/;

inputValue.replace(regexpr, "$1 $2 $3 $4");

输出结果为:

"0108470006981146 17190100 102853229 21DA192089940088"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接