正则表达式匹配两个或多个连续字符

时间:2013-01-04 23:36:26

标签: c# .net regex

使用正则表达式我想匹配一个

的单词
  • 以字母开头
  • 有英文alpahbets
  • 数字,句点(。),连字符( - ),下划线(_)
  • 不应有两个或多个连续句号或连字符或下划线
  • 可以有多个句点或连字符或下划线

例如,

  

flin..stones或flin__stones或flin - stones

是不被允许的。

  

fl_i_stones或fli_st.ones或flin.stones或flinstones

是允许的。

到目前为止我的正则表达式是 ^ [a-zA-Z] [a-zA-Z \ d ._-] + $

所以我的问题是如何使用正则表达式

1 个答案:

答案 0 :(得分:4)

您可以使用lookaheadbackreference来解决此问题。但请注意,现在您需要至少2个字符。起始字母和另一个字母(由于+)。您可能想要+*,以便第二个字符类可以重复0次或更多次:

^(?!.*(.)\1)[a-zA-Z][a-zA-Z\d._-]*$

前瞻是如何运作的?首先,这是一个负面的先行。如果内部模式找到匹配,则前瞻导致整个模式失败,反之亦然。因此,如果我们有两个连续的字符,我们可以在里面匹配一个模式。首先,我们在字符串(.*)中查找任意位置,然后我们匹配单个(任意)字符(.)和捕获它与括号。因此,一个角色进入捕获组1。然后我们要求此捕获组自身跟随(使用\1引用它)。因此内部模式将尝试在字符串中的每个单独位置(由于backtracking)是否有一个后跟自身的字符。如果找到这两个连续字符,则模式将失败。如果找不到它们,引擎会跳回到前瞻开始的位置(字符串的开头)并继续匹配实际模式。

或者,您可以将其拆分为两个单独的检查。一个用于有效字符和起始字母:

^[a-zA-Z][a-zA-Z\d._-]*$

一个用于连续字符(您可以在其中反转匹配结果):

(.)\1

这将极大地提高代码的可读性(因为它不像前瞻那样模糊),它还允许您检测模式中的实际问题并返回适当且有用的错误消息。