preg_match匹配组的名字/姓氏

时间:2017-08-22 09:26:37

标签: php regex pattern-matching names

我正在使用这个PHP regexp检查true / false一个字段是否包含一个名称,至少由一个名字/姓氏组成,然后是可选的其他中间名或首字母。

$success = preg_match("/([\x{00c0}-\x{01ff}a-zA-Z'-]){2,}(\s([\x{00c0}-\x{01ff}a-zA-Z'-]{1,})*)?\s([\x{00c0}-\x{01ff}a-zA-Z'-]{2,})/ui",$user['name'],$matches);

$output[($success ? 'hits' : 'misses')][] = ['id' => $user['id'],'email' => $user['email'],'name' => $user['name'],'matches' => $matches];

似乎在命中/未命中方面工作正常,即无论是否匹配都是真实/错误。

但是后来我试图用同样的东西来提取使用群组的名字和姓氏,我正在努力做好...

获得大量结果,如:

  "name": "Jonny Nott",
  "matches": [
    "Jonny Nott",
    "y",
    "",
    "",
    "Nott"
  ]

  "name": "Name Here",
  "matches": [
    "Name Here",
    "e",
    "",
    "",
    "Here"
  ]

  "matches": [
    "Jonathan M Notty",
    "n",
    " M",
    "M",
    "Notty"
  ]

..但我真正想要的是其中一个'匹配'总是只包含第一个名字,而一个只包含姓氏。

关于什么是错的任何指示?

3 个答案:

答案 0 :(得分:2)

每当在正则表达式中定义capturing group时,它匹配的字符串部分将作为单独的项添加到结果数组中。有两种策略可以摆脱它们:

  • 优化模式并消除冗余组(例如,单个原子周围的组 - (a)+ => a+
  • 将捕获群体转为non-capturing(\s+\w+)+ => (?:\s+\w+)+

此外,在您的情况下,如果将字母匹配部分替换为与任何字母匹配的\p{L} Unicode属性类,则可以增强模式。

使用

/[\p{L}'-]{2,}(?:\s[\p{L}'-]+)?\s[\p{L}'-]{2,}/u

请参阅regex demo

此处,只剩下一个分组(?:...),并且它是可选的,?之后使其匹配1或0次。

<强>详情

  • [\p{L}'-]{2,} - 2个或更多字母,'-
  • (?:\s[\p{L}'-]+)? - 1或0次出现空格,然后出现1个或多个字母,'-
  • \s - 空白
  • [\p{L}'-]{2,} - 2个或更多字母,'-

答案 1 :(得分:1)

尝试:

/usr/local/Homebrew/Library/

主要错误你正在重复第一组{2,} - 而不是第一组

答案 2 :(得分:1)

每当您必须使用括号但不想匹配该部分(例如空格和中间名的一部分)并在捕获组中包含量词时,请使用非捕获组(?:...)要匹配的字符(例如,名字{2,}应该在捕获组中)。

([\x{00c0}-\x{01ff}a-zA-Z'-]{2,})(?:\s(?:[\x{00c0}-\x{01ff}a-zA-Z'-]{1,})*)?\s([\x{00c0}-\x{01ff}a-zA-Z'-]{2,})