5

亲爱的 Stackoverflowianers,亲爱的 RegEx-Gurus,

我在网上搜索用于检查德语全名的合理性的正则表达式模式。我发现了许多关于没有德语变音符号的模式的帖子......从所有这些帖子和我的逻辑理解中,我一起构建了这个模式:

^([A-ZÖÄÜ]{0,1})([-a-zäöüß\.']{2,30})( {1}|-{1})([A-ZÄÖÜ]{0,1})([a-zäöüß']{0,30})( {1}|-{1})?([A-ZÖÄÜ]{0,1})([a-zäöüß']{0,30})(( {0,1}|-{1})([A-ZÖÄÜ]{0,1})([a-zäöüß']{0,30}))+$

它应该匹配以下可能的变化(现在的状态)(预期):

  • “汉斯·斯皮策”(比赛)(是)
  • “汉斯·斯皮策”(比赛)(是)
  • “Hans-peter Österreicher”(比赛)(是)
  • “Anna-Marie Pelzer-Hahnenkamp 博士”(比赛)(是)
  • “Dipl-Ing. Gerhard Meyer”(不匹配)(否)
  • “Lisa-Maria Brandner-Kapeller”(比赛)(是)
  • “约翰·麦康纳”(比赛)(是)
  • “约翰”(不匹配)(是)
  • “约翰”(匹配)(无)
  • “Osama Al Sawarri”(比赛)(是)
  • “弗兰克 F。” (不匹配)(是)
  • “Johann F. Kerner”(不匹配)(是)
  • “Johann F Kerner”(比赛)(无)
  • “李现”(匹配)(是)
  • 《李现》(不配)(无)
  • 《离赋》(不配)(无)
  • “李富”(匹配)(是)

(现在状态意味着它现在是否匹配,预期意味着它是否应该匹配)

我需要在 PHP 中将此模式用于 preg_match。

如果有人可以帮助我完善这种模式,我将非常感激。一旦它接近完美,我会将它添加到http://gskinner.com/RegExr/以供公众使用(他们有 2 或 3 个全名检查,但它们运行不正常或根本不运行)。

谢谢。提前为您提供帮助...

最好的问候,英格玛

4

4 回答 4

8

鉴于世界各地使用的大量完全有效的名称,您应该对其进行绝对最少的验证。当他们被告知他们的名字无效时,他们的名字中有连字符和撇号的人理所当然地生气。

即使试图强制首字母在它们后面加上一个点也可能是错误的,因为世界上有很多人的名字都是单字符的。

因此,我的建议是根本不验证它。

但是,如果您必须进行某种验证,那么我能给出的最佳建议是坚持过滤掉您肯定要排除的符号,并避免做任何比这更复杂的事情。

所以一个简单的模式可能看起来像这样:

/[^\$%\^\*£=~@]/

这将阻止用户在他们的名字中包含类似$或类似的符号@,因为是的,这些对于一个有效的名字来说是非常不可信的。但请确保您确实允许使用引号和连字符、逗号甚至括号,因为真实的人的姓名中确实包含这些字符。

希望有帮助。

于 2013-07-22T11:32:12.457 回答
4

因此,如果有人找到此线程并正在寻找最佳答案,那么它是:

(感谢所有在这个线程上的帮助!)

使用此正则表达式模式:

^([^\$%\^*£=~@\d]+){2,30} ([^\$%\^\.*£=~@\d]+){2,30}+$

我上面的列表(原始问题)如下所示:

可能的变化(现在的状态)(预期):

  • “汉斯·斯皮策”(比赛)(是)
  • “汉斯·斯皮策”(比赛)(是)
  • “Hans-peter Österreicher”(比赛)(是)
  • “Anna-Marie Pelzer-Hahnenkamp 博士”(比赛)(是)
  • “Dipl-Ing. Gerhard Meyer”(比赛)(是)
  • “Lisa-Maria Brandner-Kapeller”(比赛)(是)
  • “约翰·麦康纳”(比赛)(是)
  • “约翰”(不匹配)(是)
  • “约翰”(不匹配)(是)
  • “Osama Al Sawarri”(比赛)(是)
  • “弗兰克 F。” (不匹配)(是)
  • “Johann F. Kerner”(比赛)(是)
  • “Johann F Kerner”(比赛)(无)
  • “李现”(匹配)(是)
  • “李现”(比赛)(是)
  • “李福”(比赛)(是)
  • “李富”(匹配)(是)

(解释:例如“li fu”(匹配)(yes)表示,名称“li fu”匹配,“yes”预期如此)

再次感谢所有人,这种模式正是我所追求的。

最好的祝福,

“Ingmar Erdös”(比赛)(是)

PS:此模式在基于 ecma (javascript) 的正则表达式操作中非常有效,但在 PHP 中的 preg_match 等基于 prce 的操作中不适用。有人知道如何将 ecma 转换为基于 prce 的模式吗???已经上下搜索了谷歌,但根本没有在线转换器......请给我一些想法,提示或解决方案。谢谢。提前。

于 2013-07-24T06:21:55.553 回答
2

尝试单独使用 RegEx 执行此操作是不切实际的。

我发现做这种事情的最好方法是采取相反的方法。与其对潜在姓名进行字典攻击(可能使用人口普查和出生记录),不如从整体上查看姓名的模式(在这种情况下为德国姓名),并寻找可以用来识别绝对不是名字的事物。对于涉及移居德国的人的情况,您必须考虑来自其他国家的德国化名称。

不会是名字的东西包含:

  • 一个数字字符
  • 连字符以外的数学运算符
  • 斜杠、双引号和其他非预期名称字符 (&^%*$#)
  • 换行符和段落字符
  • 制表符

代码:

<?php
    $score = '0';

    $notInNames = "![0-9!@#$%^&*()_+={}|\\\\;\"\n\r\t\[\]<>?/]!";

    if(!preg_match($notInNames,$potentialName)){
       //It could be a real name
    } else {
      $score = $score+10;
    }

    if(preg_match('!(^[.-]|[.-]$)!',$potentialName)){
      $score = $score+10;
    }

    if(!preg_match('! !',$potentialName)){
    // no spaces in the name, give them a +1
      $score++;
    }

    if($score > 5){
        //not a name.

    }

?>

然后,如果您想更进一步,您可以查看德语名称的平均辅音元音比率,然后建立可接受名称的容差范围。

$vowels = "![AaEeIiOoUuäöüÖÄÜ]!";

$stripped_pn = preg_replace('! !','',$potential_name);

$length_sans_spaces = strlen($stripped_pn);
$withoutVowels = strlen(preg_replace($vowels,'',$stripped_pn));
$VowelsOnly = $length_sans_spaces - $withoutVowels;

//Consonant to Vowel Ratio
$ratio = $withoutVowels/$VowelsOnly;
于 2013-07-22T09:20:12.283 回答
1

好的,在您发表评论之后,您想要什么更清楚了。但这仍然是不可能的。其他角色呢?例如,“André Rieu”、“Bernhard Hoëcker”或您的同名“Paul Erdős”。

如果你想允许单个名字,那么不可能禁止“哈哈哈”。

而不是将所有内容都塞进一个正则表达式中。你可以做一些简单的测试:

  • 是否至少有一个空格(除非你想允许单个名字,而且有些地方人们只有一个名字)
  • 第一个字母是大写的(例如使用\p{Lu}
  • 它是否包含任何“禁止”字符,例如“$”
  • 等等
于 2013-07-22T07:46:49.353 回答