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