我正在使用这个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"
]
..但我真正想要的是其中一个'匹配'总是只包含第一个名字,而一个只包含姓氏。
关于什么是错的任何指示?
答案 0 :(得分:2)
每当在正则表达式中定义capturing group时,它匹配的字符串部分将作为单独的项添加到结果数组中。有两种策略可以摆脱它们:
(a)+
=> a+
)(\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,})