.NET 中具有重复字符和长度的正则表达式
Regex with repeated characters and length in .NET
我有一个正则表达式,我需要在其中匹配捕获中的字母部分。字母的长度可以是 1-3 个字符,并且必须是相同的字母。没有 ABC,但 A、AA 或 AAA 有效,后跟数字。我目前只能匹配A1,不能匹配AA1。我正在为正则表达式使用 .NET。
^(?<pool>([A-Z]){0,2})(?<number>(100)|[1-9]\d?)$
A1
AA2
AAA3
B5
CC7
以下正则表达式是否适合您?
\b(([A-Z]){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]){0,2})(?<number>(100|[1-9]\d?))$
只有命名的捕获组:
^(?<pool>(?<letter>[A-Z])\k<letter>{0,2})(?<number>(100|[1-9]\d?))$
对Allan简洁的回答的小补充和更正:
第三个模式在 .NET 的正则表达式引擎中没有正确匹配,因为反向引用 </code> 的编号必须与显示的 PCRE 模式(使用 regex101)不同。</p>
<p> 而不是 <code>
它需要 </code>:</p>
<pre><code>^(?<pool>([A-Z]){0,2})(?<number>(100|[1-9]\d?))$
这个 dotnetfiddle 证明了这个问题:我生成的不是 ~300 个测试用例,只有前 100 个(来自 A1-A100)被匹配。
您可以使用 .NET 正则表达式测试器 regexstorm 自行检查。
为什么?在 .NET 正则表达式和 PCRE 中引用命名捕获组与常规捕获组的方式之间存在细微差别,例如在 PHP.
乍一看,它的工作方式相同:
Captures that use parentheses are numbered automatically from left to
right based on the order of the opening parentheses in the regular
expression, starting from one**. The capture that is numbered zero is
the text matched by the entire regular expression pattern.
参考。 MSDN: Grouping Constructs in Regular Expressions
所以,虽然
most flavors number both named and unnamed capturing groups by
counting their opening parentheses from left to right. Adding a named
capturing group to an existing regex still upsets the numbers of the
unnamed groups
然而,在 .NET 中,
unnamed capturing groups are
assigned numbers first, counting their opening parentheses from left
to right, skipping all named groups. After that, named groups are
assigned the numbers that follow by counting the opening parentheses
of the named groups from left to right.
这实际上在答案中链接的 regular-expressions.info/named.html 的同一页面上进行了解释。
一个简单的例子:
要在 .NET 中匹配 1a1
,您可以使用
(?<named>(\d)a)
要在 PHP 中以类似的方式进行匹配,您必须在
中使用 \2
(?<named>(\d)a)
寓意:
Mixing named and numbered capturing groups is not recommended because
flavors are inconsistent in how the groups are numbered.
顺便说一句:
我已经准备好这个模式 \b(?<pool>([A-Z]){0,2})(?<number>(\d{1,2}(?!\d)|100))\b
但后来将注意力转移到上面概述的差异上。您还可以在链接的演示中使用 </code> vs <code>
。
我有一个正则表达式,我需要在其中匹配捕获中的字母部分。字母的长度可以是 1-3 个字符,并且必须是相同的字母。没有 ABC,但 A、AA 或 AAA 有效,后跟数字。我目前只能匹配A1,不能匹配AA1。我正在为正则表达式使用 .NET。
^(?<pool>([A-Z]){0,2})(?<number>(100)|[1-9]\d?)$
A1
AA2
AAA3
B5
CC7
以下正则表达式是否适合您?
\b(([A-Z]){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]){0,2})(?<number>(100|[1-9]\d?))$
只有命名的捕获组:
^(?<pool>(?<letter>[A-Z])\k<letter>{0,2})(?<number>(100|[1-9]\d?))$
对Allan简洁的回答的小补充和更正:
第三个模式在 .NET 的正则表达式引擎中没有正确匹配,因为反向引用 </code> 的编号必须与显示的 PCRE 模式(使用 regex101)不同。</p>
<p> 而不是 <code>
它需要 </code>:</p>
<pre><code>^(?<pool>([A-Z]){0,2})(?<number>(100|[1-9]\d?))$
这个 dotnetfiddle 证明了这个问题:我生成的不是 ~300 个测试用例,只有前 100 个(来自 A1-A100)被匹配。
您可以使用 .NET 正则表达式测试器 regexstorm 自行检查。
为什么?在 .NET 正则表达式和 PCRE 中引用命名捕获组与常规捕获组的方式之间存在细微差别,例如在 PHP.
乍一看,它的工作方式相同:
Captures that use parentheses are numbered automatically from left to right based on the order of the opening parentheses in the regular expression, starting from one**. The capture that is numbered zero is the text matched by the entire regular expression pattern.
参考。 MSDN: Grouping Constructs in Regular Expressions
所以,虽然
most flavors number both named and unnamed capturing groups by counting their opening parentheses from left to right. Adding a named capturing group to an existing regex still upsets the numbers of the unnamed groups
然而,在 .NET 中,
unnamed capturing groups are assigned numbers first, counting their opening parentheses from left to right, skipping all named groups. After that, named groups are assigned the numbers that follow by counting the opening parentheses of the named groups from left to right.
这实际上在答案中链接的 regular-expressions.info/named.html 的同一页面上进行了解释。
一个简单的例子:
要在 .NET 中匹配 1a1
,您可以使用
(?<named>(\d)a)
要在 PHP 中以类似的方式进行匹配,您必须在
中使用 \2(?<named>(\d)a)
寓意:
Mixing named and numbered capturing groups is not recommended because flavors are inconsistent in how the groups are numbered.
顺便说一句:
我已经准备好这个模式 \b(?<pool>([A-Z]){0,2})(?<number>(\d{1,2}(?!\d)|100))\b
但后来将注意力转移到上面概述的差异上。您还可以在链接的演示中使用 </code> vs <code>
。