Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 带有特殊字符的名称的正则表达式(Unicode)_Php_Javascript_Regex_Character Properties_Ruby - Fatal编程技术网

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

Php 带有特殊字符的名称的正则表达式(Unicode),php,javascript,regex,character-properties,ruby,Php,Javascript,Regex,Character Properties,Ruby,好吧,我已经读了一整天关于regex的书了,但仍然没有完全理解它。我试图做的是验证一个名称,但我在internet上可以找到的函数只使用[a-zA-Z],而不使用我需要接受的字符 我基本上需要一个正则表达式来检查名称是否至少是两个单词,并且它不包含数字或像这样的特殊字符!“#•%&/()=…,但是单词可以包含像æ、é、等字符 一个被接受的名字的例子是:“约翰·埃尔基德”或“安德烈·斯文森”一个不被接受的名字是:“汉斯”、“H4nn3安徒生”或“马丁·亨利克森!" 如果重要的话,我使用javasc

好吧,我已经读了一整天关于regex的书了,但仍然没有完全理解它。我试图做的是验证一个名称,但我在internet上可以找到的函数只使用
[a-zA-Z]
,而不使用我需要接受的字符

我基本上需要一个正则表达式来检查名称是否至少是两个单词,并且它不包含数字或像
这样的特殊字符!“#•%&/()=…
,但是单词可以包含像æ、é、等字符

一个被接受的名字的例子是:“约翰·埃尔基德”或“安德烈·斯文森”
一个不被接受的名字是:“汉斯”、“H4nn3安徒生”或“马丁·亨利克森!"

如果重要的话,我使用javascript
.match()
函数客户端,只想使用php的
preg\u replace()
服务器端(删除不匹配的字符)

任何帮助都将不胜感激

更新:
好的,多亏我把重要的部分搞定了,服务器端

但正如来自的页面所示,我找不到任何关于javascript的unicode支持的信息,因此我最终为客户端提供了半个解决方案,只需检查至少两个单词和至少5个字符,如下所示:

if(name.match(/\S+/g).length >= minWords && name.length >= 5) {
  //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
[a-zA-Z\xC0-\uFFFF]

另一种方法是按照中的建议指定所有unicode字符,最后我可能会与上面的解决方案一起执行类似的操作,但这有点不切实际。

访问此页面

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

例如:

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

这不是最好的解决方案,但如果至少有文字的话,这将产生一个结果

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

请尝试以下正则表达式:

^(?:[\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
}
你应该这样读:

if(name.match(/\S+/g).length >= minWords && name.length >= 5) {
  //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
[a-zA-Z\xC0-\uFFFF]
老实说,我不知道如何将其移植到Javascript,我甚至不确定Javascript是否支持Unicode属性,但在PHP PCRE中:

很抱歉,关于Javascript部分,我无法帮助您,但这里可能会有人提供帮助


验证

  • 约翰·埃尔基路
  • 安德烈·斯文森
  • 马尔科·达尔梅达
  • 克里斯托弗·拉库尔
使无效:

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

要替换无效字符,尽管我不确定您为什么需要它,但您只需要稍微更改它:

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

  • H4nn3安达信->Hnn安达信
  • 马丁·亨利克森!->马丁·亨利克森

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

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

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

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

关于JavaScript,它更复杂,因为JavaScript正则表达式语法不支持unicode字符属性。一个实用的解决方案是匹配如下字母:

if(name.match(/\S+/g).length >= minWords && name.length >= 5) {
  //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
[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字符表示法。

这是我用于由最多3个单词(1到60个字符)组成的奇特名称的JS正则表达式,用空格/单引号/减号分隔

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

你能详细说明一下吗example@Amit古普塔,谢谢,我做到了。:
\w
相当于
[0-9a-zA-Z!]
,取决于特定的机器语言环境,这可能(不)适用于重音字符/unicode字符,无论哪种方式,它都将始终匹配数字,而且不应该匹配。哦,似乎我必须修复我自己的许多代码块,然后:(thx提供有价值的信息!为什么
[\t]
,而不仅仅是
\s
?@Alis:\s更好。谢谢你的建议。我不是一个注册专家:谢谢你的回答,这太完美了!我现在只需要让它与js一起工作,但这不会太难,现在我至少有一些东西可以做了。:)哦,我想删除无效字符的原因是为了避免像“篡改数据”或“卷曲”这样的东西给我错误的输入,但是如果我也验证了,我想这没有什么意义:)再次感谢。@Kristofer:我已经更新了我的问题,以便更好地解释正则表达式,如果没有其他JS替代方案,您可以始终使用Ajax并调用PHP来验证它。正则表达式部分的解释非常好,给了我的不仅仅是盲目复制粘贴。JS仍然给我带来麻烦,但当/如果我找到解决方案,我会发布它到这里。找不到JS的好解决方案,但我最终还是按照问题更新中所描述的那样做了。@AlixAxel.as off 3月11日至20日