复杂的正则表达式以匹配FOO连字符和数字

时间:2019-03-14 18:28:04

标签: c# regex

我们正在尝试创建一个正则表达式,该表达式必须匹配以下字符串:

  • FOO-123123123123
  • FOO123123123123
  • FOO-123-123-123-123

它必须满足以下条件:

  • 字符串必须以FOO开头
  • foo后的
  • 符号只能是连字符(可选)和数字
  • 连续不能有多个连字符
  • 字符串的总长度不能超过50个符号且小于6个

我们已经想出了类似的东西

^FOO(-{0,1}[\d]+){6,50}$

但似乎{6,50}设置的上限不是50,不是针对字符串的总长度,而是针对此捕获组的重复

(-{0,1}[\d]+)

可以请教吗?

2 个答案:

答案 0 :(得分:3)

您可以使用

^(?=.{6,50}$)FOO-?\d+(?:-\d+)*$

请参见regex demo

详细信息

  • ^-字符串的开头
  • (?=.{6,50}$)-字符串长度应为6到50个字符
  • FOO-一个FOO子字符串
  • -?-可选的-
  • \d+-1个以上数字
  • (?:-\d+)*-0次或多次重复-,然后再重复1个数字
  • $-字符串的结尾。

注意:如果您担心\d可能会用RegexOptions.ECMAScript选项编译正则表达式,或者将\d替换为[0-9],可能会match more than ASCII digits

此外,^(?=.{6,50}$)FOO(?:-?\d+)*$也可以工作并且更短,但是在量化组内使用单个强制性模式和其他可选模式是不好的选择。在这种情况下,可以,但是在其他情况下,遵循此逻辑可能会导致灾难性的回溯。

答案 1 :(得分:0)

您可以为特定的字符检查规则使用前瞻,并为整个长度使用“正常”表达式。

^FOO(?=(?:-?\d+)+$)[-\d]{3,47}$

FOO是文字,它必须是字符串的开头。下一个块是超前((?=...))。这将检查后续字符串中是否没有相邻连字符和仅数字的规则。前瞻是非消耗性的,因此在完成前瞻之后,引擎仍在查看“ FOO”的末尾。该表达式的最后一位强制“ FOO”之后的唯一字符是连字符或数字,并且最大为3到47之间,以表示最多为6-50(减去“ FOO”的长度) )。