如何编写只匹配三个必需捕获组的正则表达式

时间:2017-02-24 01:44:18

标签: php regex pcre

我想匹配由以下内容组成的字符串:

  1. First Iniitial
  2. 中间名
  3. 姓氏+可选后缀(Jr. Sr. III等)
  4. 并且不匹配由名字+姓氏和后缀组成的字符串。

    我有以下示例数据:

    H. Graham Motion
    T. James Kelly
    J. Palacios Moli
    A. Chadwick Box
    H. Graham Motion III
    T. James Kelly, Jr.
    H. Graham Motion II
    V. Barboza Jr.
    

    我想匹配除了最后一个之外的所有字符串。

    以下是我对正则表达式的看法:

    ^(\w\.)(\s\w+\s[\sI\,\sJSr.]{0,5})*(\w+[\sI\,\sJSr.]{0,5})$
    

    但它不起作用。您可以在regex101上看到正则表达式here

1 个答案:

答案 0 :(得分:4)

我稍稍调整了你的表情并提出了^(\w\.)\s(\w+)\s(\w+(?:,?\s(?:I{0,5}|Jr\.|Sr\.))?)$。为了理智和清晰起见,我将\s移出捕获组,因为我假设您没有将中间名定义为带有前导和尾随空格的字符串。我认为我保留了你的姓氏+后缀定义的精神。

(非常详细)说明:

^                             start
(                             1st group (1st initial)
  \w\.                        one word char followed by a period
)
\s                            one whitespace char
(                             2nd group (middle name)
  \w+                         1 or more word chars
)
\s                            one whitespace char
(                             3rd group (last name + optional suffix)
  \w+                         1 or more word chars
  (?:                         non-capturing group (optional suffix)
    ,?                        0 or 1 commas
    \s                        one whitespace char
    (?:I{1,5}|Jr\.|Sr\.)      one of: 1-5 I chars, "Jr." or "Sr."
  )?                          match suffix group 0 or 1 times
)
$                             end

您会注意到我从I{0,5}更改为I{1,5},因为0个字符对我来说似乎不是一个后缀。但是,我没有看到很多人使用后缀IIIIIIIII,因此您可能希望将其更改为I{0,3}|IV|V。您可能还希望在Jr./Sr之前将姓氏更改为 require 之后的可选逗号。并且在罗马数字之前禁止

另外,请记住\w也匹配下划线和数字!并且\s匹配大多数空格字符,而不仅仅是常规空格。