创建与Java中的人员名称匹配的正则表达式

时间:2013-11-20 13:03:50

标签: java regex

我尝试使用以下语言解析名称:

  1. static final String NAME_REGEX="[A-Z][a-z]+( [A-Z][a-z]+)?";
  2. static final String NAME_REGEX="(([A-Z][a-z]+\\s?)+)|(([A-Z]\.?\s?)*([A-Z][a-z]+\\s?)+)";
  3. 我尝试过更长,更冗长的表达式,我想为这种情况创建一个小的最佳正则表达式。

    我有一个我希望使用Java正则表达式匹配的名称列表:

    B. Jack
    B.Jack Black
    B Jack Black
    B J Black
    BJ Black
    B.Jack Black
    B.J.Black
    B. Jack Black
    Jack B
    Jack B.
    Black Jack B.
    Jack B
    Black J.B
    Black JB
    Black J B
    Jack Black
    Black Jack Black
    Black J Black
    Black J. Black
    Black J.Black
    Albus P W B Dumbledore
    Albus P.W.B. Dumbledore
    

1 个答案:

答案 0 :(得分:4)

此表达式(([A-Z]\.?\s?)*([A-Z][a-z]+\.?\s?)+([A-Z]\.?\s?[a-z]*)*)执行此操作。请在接受RegexPlanetRubular之前检查所有表达式。

不幸的是,这个正则表达式也匹配:

  BlackJack
  Ms Cf Gk
  M Gh M
  Mh G M
  M G Mh

和其他几个类似的组合

我找到了一个使用单个正则表达式来匹配上面指定的所有测试用例的解决方案。我将逐步完成此操作:

这个正则表达式([A-Z][a-z]+\s?)+匹配一组单词,其中每个单词以大写字母开头,所以这将照顾:

Jack
Jack Black
Black Jack Black

现在你需要能够匹配一组大写字符,后跟可选的.和/或空格。在正则表达式语法.具有特殊含义,它匹配任何单个字符,因此.+将匹配任何字符串。

所以.必须占用\.,空格写为\s,就像你现在可能已经知道的那样。[A-Z]指的是一组大写字母,而{ {1}}显然是指一组小写字母。

所以这个正则表达式[a-z]也会匹配:

(([A-Z].?\s?)*([A-Z][a-z]+\s?)+)

现在,除了B. Jack B.Jack Black B Jack Black B J Black BJ Black B.Jack Black B.J.Black B. Jack Black 之外,您还会看到其他字符,例如.,这意味着匹配一个或没有,?表示匹配一个或多个*我们之前看到的表示匹配一个或多个,表达式+表示一个组。您可以匹配代码中的各个组,但如果找不到该组的匹配项,则值可能为null。

现在结尾的首字母()将匹配第一个正则表达式匹配的所有内容并且也匹配:

(([A-Z][a-z]+\.?\s?)+([A-Z]\.?\s?)*)

到目前为止,您必须已经发现Jack B Jack B. Black Jack B. Jack B Black J.B Black JB Black J B 将与[A-Z]\.?\s?A.匹配。因此A将更多地发生这些事件。

使用代表([A-Z]\.?\s?)*的{​​{1}}的正则表达式2和正则表达式3的组合将匹配到目前为止我们匹配的所有输入,但它会太长。相反,您可以添加正则表达式将首字母匹配到正则表达式的开头和结尾。这样的表达式将是|。这个表达式将匹配我们之前匹配的所有内容。

但是or(([A-Z]\.?\s?)*([A-Z][a-z]+\.?\s?)+([A-Z]\.?\s?)*)呢。我们目前能够匹配任何看起来像Black J Black的字符串,您可以简单地将Black J. Black添加到代表首字母的组中在最后的名称中,它看起来像Black J B

此表达式类似于[a-z]*

我还注意到,有时应用程序和其他一些地方的名称都是使用大写字母编写的,其表达式为

(A-Z\.?\s?[a-z]*)

会起作用。