2

因此,对此的要求是匹配人的姓氏,每个姓氏之间用破折号分隔。

我为此使用的基本 RegEx 是这个:

(?=\S*[-])([a-zA-ZÑñÁáÉéÍíÓóÚúÄäËëÏïÖöÜüÀàÈèÌìÒòÙù'-]+)

基本上我将其限制为拉丁字母字符,包括一些重音字符。

如果我使用以下示例,这将非常有效:

  • 佩雷斯-冈萨雷斯
  • 多明格斯-迪亚兹
  • 居梅斯-马丁内斯

但是我忘了考虑这个人只有一个姓氏的情况。

我尝试执行以下操作。

((?=\S*[-])([\ a-zA-ZÑñÁáÉéÍíÓóÚúÄäËëÏïÖöÜüÀàÈèÌìÒòÙù'-]+))|([A-Za-zÑñÁáÉéÍíÓóÚúÄäËëÏïÖöÜüÀàÈèÌìÒòÙù']+)

\ 在第一个匹配选项的允许字符中添加了一个或空格。我为没有空格的单个单词添加了 or 条件。

虽然它适用于某些情况,但有两个问题。

  1. 对于这样的用例,我认为这不是最佳的 RegEx。
  2. 我偶然发现了姓氏复杂的人的具体案例。

关于第2点,我指的是:

  • 约翰逊-德索萨

RegEx 匹配它,但它不再将破折号视为分隔符。

我不确定如何处理。

此外,由于我添加了空格,它不再尊重单词之间的破折号的要求。

我在想可能是限制名称之间的空格数,例如在姓氏之间最多允许 2 或 3 个空格,例如:

  • Pérez-De la Cruz - 这适用于我的 RegEx
  • Pérez De la Cruz-González - 这不是

可以是有效匹配。

我不是 RegEx 的专业人士,因此我们将不胜感激。

更新

我确实没有提到我需要能够将它与 JavaScript 一起使用。PHP 也可能有用,但我正在做一些浏览器验证,并且模式需要兼容。

4

1 回答 1

1

从逻辑上讲,您应该匹配一个或多个字母,然后在允许另一个包含一个或多个字母的字符串之前允许您选择的分隔字符出现一次。

PHP 代码:(演示

$names = [
    'Pérez-González',
    'Domínguez-Díaz',
    'Güemez-Martínez',
    'Johnson-De Sosa',
    'Pérez-De la Cruz',
    'smith',
    'Pérez De la Cruz-González',
    'de Gal-O\'Connell',
    'Johnson--Johnson'
];

foreach ($names as $name) {
    echo "$name is " . (!preg_match("~^\pL+(?:[- ']\pL+)*$~u", $name) ? 'in' : '') . "valid\n";
}

Javascript 代码:(片段可运行)

let names = [
      'Pérez-González',
      'Domínguez-Díaz',
      'Güemez-Martínez',
      'Johnson-De Sosa',
      'Pérez-De la Cruz',
      'smith',
      'Pérez De la Cruz-González',
      'de Gal-O\'Connell',
      'Johnson--Johnson'
    ],
    i,
    name;

for (i in names) {
    name = names[i];
    document.write("<div>" + name + " is " + (!name.match(/^\p{L}+(?:[- ']\p{L}+)*$/u) ? 'in' : '') + "valid</div>");
}

这将只允许字母序列之间的单个分隔符。如果您某人的名字是“Suzy 'Ng”,这将失败,因为它有一个空格,然后是一个撇号(两个连续的定界符)。我不知道这是否可能/真实,我只是想澄清一下。

无需环顾四周。

于 2021-04-12T02:15:22.270 回答