1

我只是用正则表达式匹配了一个字符串。

我想匹配一个包含 3 个字母/数字组合的字符串。它可能包含一个 A、B 或 L,后跟一个数字 1-3。(如果是 L,1-4)

我的问题: 当一个字母匹配多次时,我不想匹配字符串。所以A、B、L只能出现一次。

到目前为止我的表达:

(?:[A|L|B](?(?<=L)[1-4]|[1-3])){3}

此时匹配的测试字符串:

L2B1A3
B2L1A2
A1B1L4
A1A2A3

此时不匹配的字符串:

L4B4A1 (Only L can have a digit that's 4)
L2A1B (Missing digit)

我不想匹配的字符串(现在匹配):

A2A2A3 (The A, B and L only may occur one time!)
4

2 回答 2

3

如果我理解正确,这将起作用:

^(?=.*A)(?=.*B)(?=.*L)([AB][1-3]|L[1-4]){3}$

这使

L2B1A3 - 匹配
B2L1A2 - 匹配
A1B1L4 - 匹配
A1A2A3 - 不匹配
L4B4A1 - 不匹配
L2A1B - 不匹配

分解:

^ # 字符串开头
(?=.*A) # A 必须出现在字符串的任何位置
(?=.*B) # B 必须出现在字符串中的任何位置
(?=.*L) # L 必须出现在字符串的任何位置
( # 开始捕获组
  [AB][1-3] # A 或 B 和 1-3
  | # 或者
  L[1-4] # L 和 1-4
){3} # 结束组
$ # 字符串结束

必须满足三个前瞻,而主组必须匹配 3 次这一事实顾及了字母不能重复的条件。

于 2016-11-21T14:21:41.110 回答
1

只是提供一种替代方法。

^(?!.*([A-Z]).*\1)(?:[AB][1-3]|L[1-4]){3}$

带有对捕获组 1 的反向引用的负前瞻 (?!.*([A-Z]).*\1)确保字符串中只出现一次大写字母。

优点只是当将比 ABL 更多的字母添加到正则表达式时,正则表达式会更简洁。

于 2016-11-21T14:48:02.980 回答