【问题标题】:How check different spellings of a persons full name如何检查一个人全名的不同拼写
【发布时间】:2013-09-17 09:32:14
【问题描述】:

我尝试创建一个正则表达式,在一个巨大的文档中搜索一个人的全名。在文本中,姓名可以写成全称,或者名字可以缩写为单个字母或字母后跟一个点或省略。例如,我对 _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);

名字和姓氏之间可以有一个星号 (*)。

这适用于所有名字至少以某种方式存在的情况。但我不知道在省略名字时扩展表达式。你能帮帮我吗?

【问题讨论】:

  • 只是稍微相关,但\b 是“分词”。您可以显着简化表达式的开头。

标签: php regex search


【解决方案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

最后,要真正回答您的问题,您有 2 个选择。要么使整个括号名称可选,要么添加一个新的空白选项。第一个是最灵活的,因为我们也需要处理空格:

/\b((ALBERTO|A\.?)[\s\xc2-]+((JORGE|J\.?)[\s\xc2,]+)?)?(ALONSO)[\s\xc2*-]+(CALEFACCION)\b/i

请注意,如果您正在阅读匹配的部分,则需要更新您的索引。另请注意,这解决了省略第二个名称 (JORGE) 仍需要额外空格的问题。

这将匹配 A. J. ALONSO CALEFACCIONA. ALONSO CALEFACCIONALONSO CALEFACCION 之类的内容,但不匹配 J. ALONSO CALEFACCION(如果您确实需要,这只是一个小调整)

为了清楚起见,分解最后的字符串:

/\b
(
    (ALBERTO|A\.?)[\s\xc2-]+
    (
        (JORGE|J\.?)[\s\xc2,]+
    )?
)?
(ALONSO)[\s\xc2*-]+
(CALEFACCION)
\b/i

最后,这是一个奇怪的想法,但您可以将可以是首字母的名称更改为以下形式:(A(LBERTO|\.|)),这意味着您不会重复首字母(可能会导致错误)

【讨论】:

  • 你好戴夫,非常感谢。我在很多正则表达式上花费了好几个小时。我学了很多,但它仍然是我最不了解的计算机语言。
猜你喜欢
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 2012-06-16
相关资源
最近更新 更多