我使用此 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/