74

我想知道以下情况的正则表达式:

该字符串应仅包含字母。它必须以大写字母开头,后跟小写字母。然后它可以是小写字母或大写字母。

^[A-Z][a-z][A-Za-z]*$

但字符串也不能包含任何连续的大写字母。如何将该逻辑添加到正则表达式?

也就是说,HttpHandler是正确的,但是HTTPHandler是错误的。

4

5 回答 5

170

每当写[A-Z][a-z]时,都会明确承诺只处理 1960 年代的 7 位 ASCII 数据。如果真的没问题,那就好了。但如果不行,那么 Unicode 字符属性可以帮助您处理现代字符数据。

Unicode 中有三种情况,而不是两种。此外,您还有非大写字母。字母通常由\pL属性指定,并且每个字母也恰好属于五个子类别之一:

  1. 大写字母,用\p{Lu};指定 例如:AÇDZÞΣSSὩΙST
  2. 标题大写字母,用\p{Lt};指定 例如:LjDzSsᾨSt(实际上SsSt是一个大写字母,然后是一个小写字母,但是如果您分别要求 ß 和 ſt 的标题,它们就是您得到的
  3. 小写字母,用\p{Ll};指定 例如:aαçdzςσþßᾡſt
  4. 修饰字母,用\p{Lm};指定 例如:ʰʲᴴᴭʺˈˠᵠꜞ
  5. 其他字母,用\p{Lo};指定 例如:ƻאᎯᚦ京</li>

可以取其中任何一个的补码,但要小心,因为类似的东西\P{Lu}并不意味着不是大写的字母它表示任何不是大写字母的字符。

对于大写或大写字母,请使用 [\p{Lu}\p{Lt}]. 所以你可以使用你的模式:

 ^([\p{Lu}\p{Lt}]\p{Ll}+)+$

如果您不打算将第一个字母之后的字母单独限制为“外壳”字母,那么您可能更喜欢:

 ^([\p{Lu}\p{Lt}][\p{Ll}\p{Lm}\p{Lo}]+)+$

如果您尝试匹配所谓的“CamelCase”标识符,则实际规则取决于编程语言,但通常包括下划线字符和十进制数字 ( \p{Nd}),还可能包括文字美元符号和其他语言 -依赖字符。如果是这样,您可能希望将其中一些添加到上面提供的两个字符类中的一个或另一个中。

例如,您可能希望将下划线添加到两者,但仅将数字添加到第二个,留​​下:

 ^([_\p{Lu}\p{Lt}][_\p{Nd}\p{Ll}\p{Lm}\p{Lo}]+)+$

但是,如果您正在处理来自各种 RFC 和 ISO 标准的某些“词”,这些词通常被指定为仅包含 ASCII。如果是这样,你可以通过字面的[A-Z]想法来解决问题。如果它实际上不存在,那么施加这种限制是不友好的。

于 2010-10-29T13:27:42.597 回答
46

看看tchrist's answer,尤其是如果您为网络开发或更“国际化”的东西。

Oren Trutner 的回答不太正确(请参阅“RightHerE”的示例输入,该输入必须匹配,但不是)。

这是正确的解决方案:

(?!^.*[A-Z]{2,}.*$)^[A-Za-z]*$

解释:

(?!^.*[A-Z]{2,}.*$)  // don't match the whole expression if there are two or more consecutive uppercase letters
^[A-Za-z]*$          // match uppercase and lowercase letters

/编辑

解决方案的关键是负前瞻。请参阅:前瞻和后瞻零长度断言

于 2010-10-29T13:52:29.177 回答
13
^([A-Z][a-z]+)+$

这将查找大写字母后跟一个或多个小写字母的序列。连续的大写字母将不匹配,因为一次只允许一个,并且后面必须跟一个小写字母。

于 2010-10-29T08:59:58.170 回答
7

除了tchrist关于 Unicode 的优秀帖子之外,我认为您不需要带有负前瞻的复杂解决方案......您的定义需要一个大写字母,后跟至少一组(一个小写字母可选地后跟一个大写字母):

^
[A-Z]    // Start with an uppercase Letter
(        // A Group of:
  [a-z]  // mandatory lowercase letter
  [A-Z]? // an optional Uppercase Letter at the end
         // or in between lowercase letters
)+       // This group at least one time
$

它只是更紧凑,更容易阅读,我认为......

于 2014-01-06T10:29:40.170 回答
-15

如果要获取 MySQL 中至少有一个大写字母的所有员工姓名,请应用以下查询:

SELECT * FROM registration WHERE `name` REGEXP BINARY '[A-Z]';
于 2015-09-11T12:25:41.070 回答