我有一个正则表达式,我需要匹配捕获中的字母部分。这些字母的长度可以是1-3个字符,并且必须是相同的字母。没有ABC,但A,AA或AAA工作,后跟一个数字。我目前只能匹配A1,而不是AA1。我正在使用.NET作为Regex。
^(?<pool>([A-Z])\1{0,2})(?<number>(100)|[1-9]\d?)$
A1
AA2
AAA3
B5
CC7
答案 0 :(得分:4)
以下正则表达式适合您吗?
\b(([A-Z])\2{0,2}(?:100|[1-9]\d?))\b
确实接受:A1 AA2 AAA3 B5 CC7
且不符合AAAA4
或ABC123
如果您想使用命名捕获组和反向引用,那么您可以将正则表达式更改为:
^(?<pool>([A-Z]))\k<pool>{0,2}(?<number>(100|[1-9]\d?))$
让我知道它是否适合你,也看看:
https://www.regular-expressions.info/named.html
最后但并非最不重要的是,如果您希望指定的捕获组<pool>
匹配并捕获A
,AA
或AAA
,您可以使用:
^(?<pool>([A-Z])\2{0,2})(?<number>(100|[1-9]\d?))$
只有名为捕获组:
^(?<pool>(?<letter>[A-Z])\k<letter>{0,2})(?<number>(100|[1-9]\d?))$
答案 1 :(得分:2)
Allan的一个小补充和纠正的答案:
第三种模式在.NET的正则表达式引擎中不能正确匹配,因为反向引用\2
的编号必须与显示的PCRE模式不同(使用regex101)。
而不是\2
,而不是\1
:
^(?<pool>([A-Z])\1{0,2})(?<number>(100|[1-9]\d?))$
这个dotnetfiddle演示了这个问题:我只生成了前100个(来自A1-A100)的约300个测试用例。
您可以使用.NET正则表达式测试程序regexstorm自行检查。
为什么呢?在.NET regex和PCRE中如何引用与常规捕获组混合的命名捕获组之间存在细微差别,例如:用PHP。
乍一看它的工作方式相同:
使用括号的捕获从左到右自动编号 正确的基于开头括号的顺序 表达,从一个**开始。编号为零的捕获是 文本与整个正则表达式模式匹配。
参考。 MSDN: Grouping Constructs in Regular Expressions
所以,而
大多数口味都包括命名和未命名的捕获组 从左到右计算它们的开括号。添加命名 将组捕获到现有的正则表达式仍然会扰乱数据 未命名的群体
然而,在.NET中,
未命名的捕获组是 首先分配数字,从左边算出它们的左括号 向右,跳过所有命名组。之后,命名组是 通过计算左括号来分配后面的数字 从左到右的命名组。
这实际上是在答案中链接的regular-expressions.info/named.html上的同一页上解释的。
一个简单的例子:
要在.NET中匹配1a1
,您可以使用
(?<named>(\d)a)\1
要在PHP中以类似的方式匹配,您必须使用\ 2而不是
(?<named>(\d)a)\2
道德:
建议不要混用命名和编号的捕获组,因为 风味与群体的编号方式不一致。
BTW:
我已经准备好了这种模式\b(?<pool>([A-Z])\1{0,2})(?<number>(\d{1,2}(?!\d)|100))\b
,但随后将注意力转移到了上面提到的差异上。您还可以在链接演示中使用\1
vs \2
。