我尝试创建一个正则表达式,在一个巨大的文档中搜索一个人的全名。在文本中,名称可以完整写入,或者名字可以缩写为单个字母或字母后跟一个点或省略。例如,我搜索_ALBERTO JORGE ALONSO CALEFACCION_now是:
preg_match('/([;:.,&\s\xc2\-(){}!"'<>]{1})(ALBERTO|A.|A)[\s\xc2-]+
(JORGE|J.|J)?[\s\xc2,]+(ALONSO)[\s\xc2*-]+(CALEFACCION))([;:.,&\s\xc2(){}
!"'<>]{1})/i', $text, $match);
在名字和姓氏之间可以出现星号(*)。
这适用于所有名字至少以某种方式呈现的情况。但是我不知道在省略名字时扩展表达式。你能救我吗?
答案 0 :(得分:1)
让我们从简化你拥有的东西开始;
启动:
/([;:.,&\s\xc2\-(){}!"'<>]{1})(ALBERTO|A.|A)[\s\xc2-]+(JORGE|J.|J)?[\s\xc2,]+(ALONSO)[\s\xc2*-]+(CALEFACCION)([;:.,&\s\xc2(){}!"'<>]{1})/i
正如我在评论中所说,\b
是“断字”,所以你可以简化很多:
/\b(ALBERTO|A.|A)[\s\xc2-]+(JORGE|J.|J)?[\s\xc2,]+(ALONSO)[\s\xc2*-]+(CALEFACCION)\b/i
(额外奖励:它现在不会与任何一方的角色匹配,并且会在文本的开头和结尾处匹配)
接下来,您可以使用?
标记作为点(应该按顺序转义; .
是特殊的,意味着“匹配任何内容”)
/\b(ALBERTO|A\.?)[\s\xc2-]+(JORGE|J\.?)?[\s\xc2,]+(ALONSO)[\s\xc2*-]+(CALEFACCION)\b/i
最后,要真正回答你的问题,你有两个选择。使整个括号内的名称可选,或添加一个新的空白选项。第一个是最灵活的,因为我们也需要处理空白:
/\b((ALBERTO|A\.?)[\s\xc2-]+((JORGE|J\.?)[\s\xc2,]+)?)?(ALONSO)[\s\xc2*-]+(CALEFACCION)\b/i
请注意,如果您正在阅读匹配的部分,则需要更新索引。另请注意,这解决了省略第二个名称(JORGE)仍然需要额外空间的问题。
这会匹配A. J. ALONSO CALEFACCION
,A. ALONSO CALEFACCION
和ALONSO CALEFACCION
之类的内容,但不会匹配J. ALONSO CALEFACCION
(如果您确实需要,则只需进行一些小调整)
为了清晰起见,打破最后一个字符串:
/\b
(
(ALBERTO|A\.?)[\s\xc2-]+
(
(JORGE|J\.?)[\s\xc2,]+
)?
)?
(ALONSO)[\s\xc2*-]+
(CALEFACCION)
\b/i
最后,这是一个奇怪的想法,但你可以改变这个形式的首字母名称:(A(LBERTO|\.|))
,这意味着你不会重复首字母(潜在的错误来源)