php - preg_match 名字/姓氏匹配组

标签 php regex pattern-matching names

我使用此 PHP 正则表达式来检查字段是否包含名称(至少包含名字/姓氏,然后是可选的其他中间名或缩写)的 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"
  ]

..但我真正想要的是其中一个“匹配项”始终仅包含名字,而一个“匹配项”始终仅包含姓氏。

有什么问题可以指出吗?

最佳答案

每当您定义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 个或更多字母、'-

关于php - preg_match 名字/姓氏匹配组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45813761/

相关文章:

php - CodeIgniter 4 重定向功能不起作用

javascript - 需要有关 jQuery 将数据发布到 php 文件的帮助

algorithm - 在字符串中查找部分子字符串

正则表达式从行尾找到第四个逗号

php - 高度不行

php - CodeIgniter 路由 - 404 错误

javascript - firefox 3.6.20 正则表达式给出不一致的结果

regex - 关于如何在 Nginx 位置 block 部分使用正则表达式的指南?

ruby-on-rails - 基于正则表达式的自定义验证错误消息

java - 匹配特定索引