.NET中具有重复字符和长度的正则表达式
Posted
技术标签:
【中文标题】.NET中具有重复字符和长度的正则表达式【英文标题】:Regex with repeated characters and length in .NET 【发布时间】:2018-10-12 02:01:51 【问题描述】:我有一个正则表达式,我需要匹配捕获中的字母部分。字母长度可以是 1-3 个字符,并且必须是相同的字母。没有 ABC,但 A、AA 或 AAA 有效,后跟一个数字。我目前只能匹配 A1,不能匹配 AA1。我将 .NET 用于正则表达式。
^(?<pool>([A-Z])\10,2)(?<number>(100)|[1-9]\d?)$
A1
AA2
AAA3
B5
CC7
【问题讨论】:
您能添加您正在使用的编程语言吗? 喜欢This? 我希望我参加派对还不算太晚。 :) – wp78de 1 小时前 【参考方案1】:以下正则表达式对您有用吗?
\b(([A-Z])\20,2(?:100|[1-9]\d?))\b
DEMO
它接受:A1 AA2 AAA3 B5 CC7
,但不匹配 AAAA4
或 ABC123
如果您想对它们使用命名捕获组和反向引用,那么您可以将您的正则表达式更改为:
^(?<pool>([A-Z]))\k<pool>0,2(?<number>(100|[1-9]\d?))$
DEMO
让我知道它是否适合你,也看看:
https://www.regular-expressions.info/named.html
最后但同样重要的是,如果您希望命名的捕获组 <pool>
匹配并捕获 A
、AA
或 AAA
,您可以使用:
^(?<pool>([A-Z])\20,2)(?<number>(100|[1-9]\d?))$
DEMO
只有命名的捕获组:
^(?<pool>(?<letter>[A-Z])\k<letter>0,2)(?<number>(100|[1-9]\d?))$
DEMO
【讨论】:
AA 不匹配\1
作为反向引用。看我的回答。
此答案适用于在线测试仪,但由于某种原因不适用于 .NET。有什么线索吗?【参考方案2】:
对艾伦的简洁答案的一个小补充和更正:
第 3 个模式在 .NET 的正则表达式引擎中没有正确匹配,因为反向引用 \2
的编号必须与所示 PCRE 模式中的编号不同(使用 regex101)。
应该是\1
,而不是\2
:
^(?<pool>([A-Z])\10,2)(?<number>(100|[1-9]\d?))$
这个dotnetfiddle 演示了这个问题:我生成的不是大约 300 个测试用例,而是只匹配前 100 个(来自 A1-A100)。
您可以使用 .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
道德:
不建议混合命名和编号的捕获组,因为 各组的编号方式不一致。
顺便说一句:
我已经准备好了这个模式\b(?<pool>([A-Z])\10,2)(?<number>(\d1,2(?!\d)|100))\b
,但随后将注意力转移到了上面概述的差异上。您还可以在链接的演示中使用\1
与\2
。
【讨论】:
以上是关于.NET中具有重复字符和长度的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章
使用python正则表达式在字符串中搜索长度为6或更长的特定重复(mnr)