西班牙姓氏由三部分组成:
- 父姓,
- 可选的母亲姓名,
- 可选配偶的父姓。
这三个部分中的每一个都是一个单独的词,前面可以有“德”、“德尔”、“德拉”、“德洛斯”或“德拉斯”。这些前缀中的每一个都以大写字母开头,每个部分只能有一个前缀。配偶的父姓与其余部分之间用“德”字隔开(没有大写字母)。
因此,有效的姓氏为:
- 佩雷斯
- 佩雷斯·德莱昂
- 洛佩斯德洛佩斯
- 德拉奥卡奥尔多涅斯
- 卡斯蒂略拉米雷斯德瓦莱
我可以用这个正则表达式来解析这些名称:
^((?:De |Del |De La |De Los |De Las )?\w+)?( (?:De |Del |De La |De Los |De Las )?\w+)?( de (?:De |Del |De La |De Los |De Las )?\w+)?$
1.)这个难看的正则表达式可以简化吗?
2.)当父姓和母姓相同时,在它们之间插入“y”,所以“López y Lópey de De León”和“Pérez y Pérez”都有效,但“López y Pérez”和“Gómez y de Gómez”无效,我该如何描述这种情况?
非常感谢。
3条答案
按热度按时间eqoofvh91#
确切的答案取决于您使用的编程语言和/或正则表达式引擎,但对于大多数实现,您应该能够执行以下操作:
(1.)创建一个单独的正则表达式,匹配名称的单个部分,然后将其包含在最终的正则表达式中,例如,在Perl中:
(我假设您在第一次捕获后不需要
?
,否则您将匹配空字符串。)$name2
就是要匹配的正则表达式。(2.)严格地说,正确的计算机理论正则表达式不能测试出现在字符串中一个点的任意子串是否也出现在另一个点。然而,大多数正则表达式实现(例如,Perl兼容的“正则表达式”)实际上比真实的的正则表达式引擎支持更多的功能,所以你可以使用如下反向引用:
在PCRE中,
\3
匹配的字符串与第三个(...)
组匹配的字符串完全相同。如果由于某种原因无法使用反向引用,则唯一的选择是使用如下正则表达式:然后,如果在匹配之后定义了
$3
和$4
,则测试它们是否相等(注意,上述两个方法都允许“López López”这样的名称不带“y”;如果你想禁止这些,那就有点难了。)h4cxqtbf2#
下面是我的尝试,它似乎与给出的例子一起工作:
9w11ddsr3#
与使用正则表达式不同,有一个服务在这方面做得非常出色:https://www.nameapi.org/en/demos/name-parser/。它是开源的,但是它没有使用正则表达式,而是从电话簿中收集数据,以及一组非常复杂的规则。