【问题标题】:Accept international name characters in RegEx接受 RegEx 中的国际名称字符
【发布时间】:2011-11-04 18:10:47
【问题描述】:

我一直在与 RegEx 斗争,所以如果这看起来是解决我的问题的糟糕方法,请原谅我。

当用户输入名字和姓氏时,我一开始只使用基本的,检查大小写、空格、撇号和连字符

if (!preg_match("/^[a-zA-Z\s'-]+$/", $name)) { // Error }

现在我意识到这不是最好的,因为人们可以拥有以下内容:Martin Luther King, Jr. 博士(带逗号和句号)。所以我认为通过将其更改为 this 会使其更有效。

if (!preg_match("/^[a-zA-Z\s,.'-]+$/", $name)) { // Error }

然后我在我的 Facebook 上看到一个我认识的女孩名字,她把她的名字写成 Siân,这让我想到了包含变音符号以及日文/中文/韩文/俄文字符的名字。所以我开始搜索并找到方法,像这样在其中写下每个字符。

if (!preg_match("/^[a-zA-Z\sàáâäãåèéêëìíîïòóôöõøùúûüÿýñçčšžÀÁÂÄÃÅÈÉÊËÌÍÎÏÒÓÔÖÕØÙÚÛÜŸÝÑßÇŒÆČŠŽ∂ð ,.'-]+$/u", $first_name)) { // Error }

正如您可以想象的那样,它非常冗长,我很确定有一个更简单的 RegEx 可以实现这一点。就像我说的,我已经四处寻找,但这是我能做的最好的。

那么,检查大小写字符、逗号、句号、撇号、连字符、变音符号、拉丁语、日语/俄语等的好方法是什么

【问题讨论】:

  • 除非您先进行标准化,否则这将无法正常工作,而且通常甚至在那时也无法正常化。

标签: php regex


【解决方案1】:

您可以使用 Unicode 字符类。 \pL 几乎涵盖了所有字母符号。
http://php.net/manual/en/regexp.reference.unicode.php

 if (!preg_match("/^[a-zA-Z\s,.'-\pL]+$/u", $name))

另请参阅http://www.regular-expressions.info/unicode.html,但请注意 PHP/PCRE 只能理解缩写的类名。

【讨论】:

  • 啊,非常感谢,为什么我不能早点找到这个,哈!你能告诉我缩写的类名是什么意思吗?
  • @HelloJoe:这不是最明显的功能。很晚才在 PHP 手册中找到文档。缩写:例如 PCRE 仅支持 \p{L} 不支持 \p{Letter}\p{Russian}
  • 你有 ,.' 在那里,你可能想删除它,因为它是一个名字。
  • 完美,谢谢。但表达式包含一个小错误,更正一个:/^[a-zA-Z\s,.'\-\pL]+$/u/^[a-z\s,.'-\pL]+$/iu
  • 不包括 æøå 或 ß
【解决方案2】:

\pL 已经包含a-zA-Z,因此上述模式"/^[a-zA-Z\s,.'-\pL]+$/u" 可以简化为

"/^[\s,.'-\pL]+$/"

也不需要修饰符u

【讨论】:

  • 虽然我最初打算 +1 是因为提到 a-zA-Z 是多余的,但我必须提到 u 修饰符肯定是必需的,否则 PHP 不支持多字节编码。
  • 我在我的 DEV 机器上对其进行了测试,它在没有 u 修饰符的情况下为我工作
  • 您使用的是 UTF-8 或其他多字节编码,还是单字节编码,例如 ASCII 或 latin1?单字节编码不需要u 修饰符。
【解决方案3】:

允许使用其他类型的标点符号可能会放宽限定条件。

应该限制的一件事是至少需要一个字母。

if (!preg_match("/^[\s,.'-]*\p{L}[\p{L}\s,.'-]*$/u", $name))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-08
    • 2011-05-24
    • 1970-01-01
    • 2010-09-08
    • 2012-11-10
    • 2018-08-27
    • 2011-10-15
    • 1970-01-01
    相关资源
    最近更新 更多