Skip to main content
 首页 » 编程设计

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

2024年02月20日27EasonJim

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

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

例如,

flin..stones or flin__stones or flin--stones

不允许。

fl_i_stones or fli_st.ones or flin.stones or flinstones

是允许的。

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

所以我的问题是如何使用正则表达式来做到这一点

请您参考如下方法:

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

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

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

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

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

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

(.)\1 

这会大大提高代码的可读性(因为它不像前瞻那样晦涩难懂),而且还能让您检测模式中的实际问题并返回适当且有用的错误消息。