繁体   English   中英

带有特殊字符的名称的正则表达式(Unicode)

[英]Regex for names with special characters (Unicode)

好的,我整天都在阅读正则表达式,但仍然不太了解它。 我想做的是验证名称,但是我在互联网上可以找到的功能仅使用[a-zA-Z] ,而我需要接受的字符[a-zA-Z]

我基本上需要一个正则表达式来检查名称至少是两个单词,并且不包含数字或特殊字符,如!"#¤%&/()=... ,但是这些单词可以包含æ, é,Â等...

可接受名称的示例是:“ JohnElkjærd”或“AndréSvenson”
不可接受的名称为:“ Hans ”,“ H 4 nn 3 Andersen”或“ Martin Henriksen

如果重要的话,我使用javascript .match()函数客户端,并且只想在“负面”服务器端使用php的preg_replace() (删除不匹配的字符)。

任何帮助将非常感激。

更新:
好的,多亏了Alix Axel的回答,我把重要的一面放在了服务器端。

但是正如LightWing答案中的页面所建议的那样,我无法找到有关对javascript的unicode支持的任何信息,因此我最终为客户端提供了一半的解决方案,仅检查了至少两个单词和最少5个字符,如下所示:

if(name.match(/\S+/g).length >= minWords && name.length >= 5) {
  //valid
}

一种替代方法是按照shifty的答案中的建议指定所有unicode字符,我可能最终会像上面的解决方案那样做类似的事情,但这有点不切实际。

尝试以下正则表达式:

^(?:[\p{L}\p{Mn}\p{Pd}\'\x{2019}]+\s[\p{L}\p{Mn}\p{Pd}\'\x{2019}]+\s?)+$

在PHP中,这转换为:

if (preg_match('~^(?:[\p{L}\p{Mn}\p{Pd}\'\x{2019}]+\s[\p{L}\p{Mn}\p{Pd}\'\x{2019}]+\s?)+$~u', $name) > 0)
{
    // valid
}

您应该这样阅读:

^   # start of subject
    (?:     # match this:
        [           # match a:
            \p{L}       # Unicode letter, or
            \p{Mn}      # Unicode accents, or
            \p{Pd}      # Unicode hyphens, or
            \'          # single quote, or
            \x{2019}    # single quote (alternative)
        ]+              # one or more times
        \s          # any kind of space
        [               #match a:
            \p{L}       # Unicode letter, or
            \p{Mn}      # Unicode accents, or
            \p{Pd}      # Unicode hyphens, or
            \'          # single quote, or
            \x{2019}    # single quote (alternative)
        ]+              # one or more times
        \s?         # any kind of space (0 or more times)
    )+      # one or more times
$   # end of subject

老实说,我不知道如何将其移植到Javascript,我什至不确定Javascript是否支持Unicode属性,但是在PHP PCRE中,@ IDEOne.com似乎可以完美地工作

$names = array
(
    'Alix',
    'André Svenson',
    'H4nn3 Andersen',
    'Hans',
    'John Elkjærd',
    'Kristoffer la Cour',
    'Marco d\'Almeida',
    'Martin Henriksen!',
);

foreach ($names as $name)
{
    echo sprintf('%s is %s' . "\n", $name, (preg_match('~^(?:[\p{L}\p{Mn}\p{Pd}\'\x{2019}]+\s[\p{L}\p{Mn}\p{Pd}\'\x{2019}]+\s?)+$~u', $name) > 0) ? 'valid' : 'invalid');
}

很抱歉,我无法在Javascript部分方面为您提供帮助,但可能有人会在这里帮您。


验证

  • 约翰·埃尔克雅德
  • 安德烈·斯文森
  • Marco d'Almeida
  • 克里斯托弗·拉库尔

无效

  • 汉斯
  • H4nn3安徒生
  • 马丁·亨里克森!

要替换无效字符,尽管我不确定为什么需要这样做,但您只需要对其稍作更改即可:

$name = preg_replace('~[^\p{L}\p{Mn}\p{Pd}\'\x{2019}\s]~u', '$1', $name);

例子:

  • H4nn3安徒生->恩安徒生
  • 马丁·亨里克森! ->马丁·亨里克森

请注意,您始终需要使用u修饰符。

关于JavaScript则比较棘手,因为JavaScript Regex语法不支持Unicode字符属性。 务实的解决方案是匹配以下字母:

[a-zA-Z\xC0-\uFFFF]

这允许使用所有语言的字母,并排除数字和键盘上常见的所有特殊(非字母)字符。 这是不完善的,因为它还允许使用非字母的unicode特殊符号,例如表情符号,雪人等。 但是,由于这些符号通常在键盘上不可用,因此我认为不会偶然输入它们。 因此,根据您的要求,它可能是可接受的解决方案。

这是对上述@Alix的绝佳答案的优化。 它消除了两次定义字符类的需要,并允许更轻松地定义任意数量的必需单词。

^(?:[\p{L}\p{Mn}\p{Pd}\'\x{2019}]+(?:$|\s+)){2,}$

它可以细分如下:

^         # start
  (?:       # non-capturing group
    [         # match a:
      \p{L}     # Unicode letter, or
      \p{Mn}    # Unicode accents, or
      \p{Pd}    # Unicode hyphens, or
      \'        # single quote, or
      \x{2019}  # single quote (alternative)
    ]+        # one or more times
    (?:       # non-capturing group
      $         # either end-of-string
    |         # or
      \s+       # one or more spaces
    )         # end of group
  ){2,}     # two or more times
$         # end-of-string

本质上,这就是说要找到由字符类定义的单词,然后找到一个或多个空格或行尾。 最后的{2,}告诉您至少要找到两个单词才能使匹配成功。 这样可以确保OP的“ Hans”示例不匹配。


最后,由于我在寻找类似的解决方案时发现了这个问题,因此下面是可在Ruby 1.9+中使用的正则表达式

\A(?:[\p{L}\p{Mn}\p{Pd}\'\U+2019]+(?:\Z|\s+)){2,}\Z

主要的更改是使用\\ A和\\ Z作为字符串的开头和结尾(而不是行)和Ruby的Unicode字符表示法。

您可以将允许的特殊字符添加到正则表达式中。

例:

[a-zA-ZßöäüÖÄÜæé]+

编辑:

不是最好的解决方案,但是如果至少有单词的话,这会产生结果。

[a-zA-ZßöäüÖÄÜæé]+\s[a-zA-ZßöäüÖÄÜæé]+

这是我使用的JS正则表达式,最多包含3个字(1到60个字符),以空格/单引号/减号分隔

^([a-zA-Z\xC0-\uFFFF]{1,60}[ \-\']{0,1}){1,3}$

检查输入字符串时,您可以

  • trim()删除前导/尾随空格
  • 与[^ \\ w \\ s]匹配以检测非单词\\非空白字符
  • 与\\ s +匹配以获取等于单词数+ 1的单词分隔符数。

但是,我不确定\\ w速记中是否包含带重音符号的字符,但是它应该属于“单词字符”类别。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM