正则表达式匹配由破折号分隔的单词或仅匹配单个单词
RegEx to match either words separated by dash or just a single word
所以,这个要求是匹配人的姓氏,每个姓氏之间用破折号分隔。
我为此使用的基本 RegEx 是这个:
(?=\S*[-])([a-zA-ZÑñÁáÉéÍíÓóÚúÄäËëÏïÖöÜüÀàÈèÌìÒòÙù'-]+)
基本上我将它限制为拉丁字母字符,包括一些重音字符。
如果我使用像这样的示例,这将非常有效:
- 佩雷斯-冈萨雷斯
- Dom恩格斯-迪亚斯
- 格梅斯-马丁内斯
但是我忘了考虑这个人只有一个姓氏的情况
我尝试执行以下操作。
((?=\S*[-])([\ a-zA-ZÑñÁáÉéÍíÓóÚúÄäËëÏïÖöÜüÀàÈèÌìÒòÙù'-]+))|([A-Za-zÑñÁáÉéÍíÓóÚúÄäËëÏïÖöÜüÀàÈèÌìÒòÙù']+)
我在第一个匹配选项的允许字符中添加了一个\
或space。我在没有 spaces.
的情况下为单个单词添加了一个或条件
虽然它适用于某些情况,但存在 2 个问题。
- 我不认为它是这种用例的最佳正则表达式。
- 我偶然发现了具有复杂姓氏的人的具体案例。
关于第2点,我指的是:
- 约翰逊-德索萨
RegEx 匹配它,但它不再将破折号作为分隔符。
我不知道该如何处理。
此外,由于我添加了 space,它不再遵守单词之间破折号的要求。
我在想的可能是限制名字之间 space 的数量,比如在姓氏之间最多允许 2 或 3 个 space,这样的例子如下:
- Pérez-De la Cruz - 这适用于我的正则表达式
- Pérez De la Cruz-González - 这不是
可以是有效匹配。
我不是 RegEx 专业人士,因此非常感谢您的帮助。
更新
我确实没有提到我需要能够将其与 JavaScript 一起使用。 PHP 也可能有用,但我正在做一些浏览器验证并且模式需要兼容。
从逻辑上讲,您应该匹配一个或多个字母,然后允许出现一次您选择的定界字符,然后再允许另一个包含一个或多个字母的字符串。
PHP代码:(Demo)
$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”,这将失败,因为它有一个 space 然后是一个撇号(两个连续的分隔符)。我不知道这是不是possible/real,我只是想澄清一下。
不需要环顾四周。
所以,这个要求是匹配人的姓氏,每个姓氏之间用破折号分隔。
我为此使用的基本 RegEx 是这个:
(?=\S*[-])([a-zA-ZÑñÁáÉéÍíÓóÚúÄäËëÏïÖöÜüÀàÈèÌìÒòÙù'-]+)
基本上我将它限制为拉丁字母字符,包括一些重音字符。
如果我使用像这样的示例,这将非常有效:
- 佩雷斯-冈萨雷斯
- Dom恩格斯-迪亚斯
- 格梅斯-马丁内斯
但是我忘了考虑这个人只有一个姓氏的情况
我尝试执行以下操作。
((?=\S*[-])([\ a-zA-ZÑñÁáÉéÍíÓóÚúÄäËëÏïÖöÜüÀàÈèÌìÒòÙù'-]+))|([A-Za-zÑñÁáÉéÍíÓóÚúÄäËëÏïÖöÜüÀàÈèÌìÒòÙù']+)
我在第一个匹配选项的允许字符中添加了一个\
或space。我在没有 spaces.
虽然它适用于某些情况,但存在 2 个问题。
- 我不认为它是这种用例的最佳正则表达式。
- 我偶然发现了具有复杂姓氏的人的具体案例。
关于第2点,我指的是:
- 约翰逊-德索萨
RegEx 匹配它,但它不再将破折号作为分隔符。
我不知道该如何处理。
此外,由于我添加了 space,它不再遵守单词之间破折号的要求。
我在想的可能是限制名字之间 space 的数量,比如在姓氏之间最多允许 2 或 3 个 space,这样的例子如下:
- Pérez-De la Cruz - 这适用于我的正则表达式
- Pérez De la Cruz-González - 这不是
可以是有效匹配。
我不是 RegEx 专业人士,因此非常感谢您的帮助。
更新
我确实没有提到我需要能够将其与 JavaScript 一起使用。 PHP 也可能有用,但我正在做一些浏览器验证并且模式需要兼容。
从逻辑上讲,您应该匹配一个或多个字母,然后允许出现一次您选择的定界字符,然后再允许另一个包含一个或多个字母的字符串。
PHP代码:(Demo)
$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”,这将失败,因为它有一个 space 然后是一个撇号(两个连续的分隔符)。我不知道这是不是possible/real,我只是想澄清一下。
不需要环顾四周。