【问题标题】:Validate Title Case Full Name with Regex使用正则表达式验证标题大小写全名
【发布时间】:2017-10-06 14:38:56
【问题描述】:

为了学习正则表达式,我正在解决一些训练和学习的问题。这就是问题所在,我知道这可能不是使用 Regex 的最佳方式,而且我的 Regex 是一团糟,但我喜欢这个挑战。

问题:

  • 名字必须是Title Case
  • 里面的一些小写单词有例外;
  • 还有一些名字,例如:McDonald、MacDuff、D'Estoile
  • 接受带有 '- 的名称,有时它们是 o'Brien、O'brien、O'Brien、O'Brien 或 'Ehu Kali。
  • 名称的开头和结尾没有空格;
  • 每个全名之间不超过一个空格;
  • . 如果不是单独的,则被接受,例如:Dan。 Ferdnand(不接受)和 Dan G. Ferdnand(接受)
  • 不接受数字和符号
  • 但是,罗马数字被接受,而不是标题大小写,例如:伊丽莎白二世
  • 有些名字可以单独使用,例如:Akihito(日本王子)
  • 接受某些国家/地区常见的一些特殊字符,例如:Valeh ßlÿsgÿroğlu、Lażżru Role、Alaksiej Taraškievič

正则表达式

代码是

^(?![ ])(?!.*(?:\d|[ ]{2}|[!$%^&*()_+|~=`\{\}\[\]:";<>?,\/]))(?:(?:e|da|do|das|dos|de|d'|la|las|el|los|l'|al|of|the|el-|al-|di|van|der|op|den|ter|te|ten|ben|ibn)\s*?|(?:[A-ZàáâäãåąčćęèéêëėįìíîïłńòóôöõøùúûüųūÿýżźñçčšžÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßÇŒÆČŠŽ∂ð'][^\s]*\s*?)(?!.*[ ]$))+$

还有带有验证列表的Regex101

参考文献

到目前为止我所尝试的都是基于这些:

不工作

我做了这个正则表达式,但不知道如何让它无法识别以下匹配的情况:

  • 大写字母
  • 替代字母

那些不是而且应该:

  • UrxanƏbűlhəsənzadə
  • 伊斯米特·贾法罗夫
  • Şükür Hagverdiyev
  • Űmid Abdurrahimov
  • Ġerardo Seralta
  • Ċikku 巴黎

问题

有没有办法优化这个正则表达式(怪物)?

我该如何解决前面提到的无法正常工作的问题?

p.s.:带有验证示例的名称列表可以在 Regex101 的链接上找到。

【问题讨论】:

  • 感谢您抽出时间来写一篇写得很好的帖子。您正在帮助我恢复对正确书写和格式问题的信心!
  • 很难用 1 个正则表达式验证名称并涵盖所有语言。 No more than one space inside Name; 所以我的名字不被接受? :'( ...无论如何,如果您正在练习尝试debuggex.com,它对我有很大帮助。
  • 我会编辑/改写,每个名字之间不超过两个空格
  • 请注意,语言和工具实现正则表达式的方式存在差异(通常表示为不同的正则表达式“风格”)。您是否决定使用一种风格(您的 regex101 链接会建议使用 JavaScript)?如果是这样,请告诉我们哪一个可能会导致不同的答案,尤其是关于非 ascii 字符处理的主题。

标签: regex names


【解决方案1】:

简介

鉴于您是如何学习正则表达式并且没有指定要使用的正则表达式风格,我选择了 PCRE,因为它在正则表达式领域有广泛的支持。


代码

See this regex in use here

(?(DEFINE)
    (?# Definitions )
    (?<valid_nameChars>[\p{L}\p{Nl}])
    (?<valid_nonNameChars>[^\p{L}\p{Nl}\p{Zs}])
    (?<valid_startFirstName>(?![a-z])[\p{L}'])
    (?<valid_upperChar>(?![a-z])\p{L})
    (?<valid_nameSeparatorsSoft>[\p{Pd}'])
    (?<valid_nameSeparatorsHard>\p{Zs})
    (?<valid_nameSeparators>(?&valid_nameSeparatorsSoft)|(?&valid_nameSeparatorsHard))
    (?# Invalid combinations )
    (?<invalid_startChar>^[\p{Zs}a-z])
    (?<invalid_endChar>.*[^\p{L}\p{Nl}.\p{C}]$)
    (?<invalid_unaccompaniedSymbol>.*(?&valid_nameSeparatorsHard)(?&valid_nonNameChars)(?&valid_nameSeparatorsHard))
    (?<invalid_overTwoUpper>(?:(?&valid_nameChars)*\p{Lu}){3})
    (?<invalid>(?&invalid_startChar)|(?&invalid_endChar)|(?&invalid_unaccompaniedSymbol)|(?&invalid_overTwoUpper))
    (?# Valid combinations )
    (?<valid_name>(?:(?:(?&valid_nameChars)|(?&valid_nameSeparatorsSoft))*(?&valid_nameChars)+(?:(?&valid_nameChars)|(?&valid_nameSeparatorsSoft))*)+\.?)
    (?<valid_firstName>(?&valid_startFirstName)(?:\.|(?&valid_name)*))
    (?<valid_multipleName>(?&valid_firstName)(?=.*(?&valid_nameSeparators)(?&valid_upperChar))(?:(?&valid_nameSeparatorsHard)(?&valid_name))+)
    (?<valid>(?&valid_multipleName)|(?&valid_firstName))
)
^(?!(?&invalid))(?&valid)$

结果

输入

== 1NcOrrect N4M3S ==
CAPITAL LETTER
AlTeRnAtE LeTtEr
Natalia maria
Natalia aria
Natalia orea
Maria dornelas
Samuel eto'
Miguel lasagna
Antony1 de Home Ap*ril
Ap*ril Willians
Antony_ de Home Apr+il
Ant_ony de Home Apr#il
Antony@ de Ho@me Apr^il
Maria  Silva
Maria silva
maria Silva
 Maria Silva
Maria Silva 
Maria / Silva
Maria . Silva
John W8

==Correct Names==
Urxan Əbűlhəsənzadə
İsmət Jafarov
Şükür Hagverdiyev
Űmid Abdurrahimov
Ġerardo Seralta
Ċikku Paris
Hind ibn Sheik
Colop-U-Uichikin
Lażżru Role
Alaksiej Taraškievič
Petruso Husoǔski
Sumu-la-El
Valeh ßlÿsgÿroğlu
'Arab al-Rashayida
Tariq al-Hashimi
Nabeeh el-Mady
Tariq Al-Hashimi
Brian O'Conner
Maria da Silva
Maria Silva
Maria G. Silva
Maria McDuffy
Getúlio Dornelles Vargas
Maria das Flores
John Smith
John D'Largy
John Doe-Smith
John Doe Smith
Hector Sausage-Hausen
Mathias d'Arras
Martin Luther King Jr.
Ai Wong
Chao Chang
Alzbeta Bara
Marcos Assunção
Maria da Silva e Silva
Juscelino Kubitschek de Oliveira
Maria da Costa e Silva
Samuel Eto'o
María Antonieta de las Nieves
Eugène
Antòny de Homé April
àntony de Home ùpril
Antony de Home Aprìl
Pierre de l'Estache
Pierre de L'Estoile
Akihito
Nadine Schröder
Anna A. Møller
D. Pedro I
Pope Benedict XVI
Marsibil Ragnarsdóttir
Natanaël Morel
Isaac De la Croix
Jean-Michel Bozonnet
Qutaibah Mu'tazz Abadi
Rushd Jawna' Kassab
Khaldun Abdul-Qahhar Sabbag
'Awad Bashshar Asker
Al B. Zellweger
Gunnleif Snæ-Ulfsson
Käre Toresson
Sorli Ærnmundsson
Arnkel Øystæinsson
Ástríður Dórey
Åsmund Kåresson
Yahatti-Il
Ipqu-Annunitum
Nabu-zar-adan
Eskopas Cañaverri
Botolph of Langchester
Aelfhun the Cantrell
Fraco di Natale
Fraco Di Natale
Iván de Luca
Iván De Luca
Man'nah
Atabala Aüamusalü
Ramiz Ağasəfalu
Dadaş Aghakhanov
Fÿrxad Mübarizlı
Vaclaǔ Šupa
Yakiv Volacič
Flor Van Vaerenbergh
Flor van Vaerenbergh
Edwin van der Sar
Husein Ekmečić
Álvaro Guimarães Alencar
Phone U Yaza Arkar
Seocan MacGhille
X'wat'e Tlekadugovy
Albert-Jan Bootsveld
Maurits-jan Kuipers op den Kollenstaart
Elco ter Hoek
Robbert te Poele
Aad ten Have
'Ehu Kali
Ho'opa'a Loni
Aukanai'i Mahi'ai
Kalman ben Tal El
Żytomir Roszkowski
K'awai

==EXTRA== only if possible, strange ones
Maol-Moire Mac'IlleBhuidh
Tòmas MacIlleChruim
Aindreas MacIllEathain
Eanruig MacGilleBhreac
Peadar MacGilleDhonaghart
Maolmhuire MacGill-Eain
Eanruig MacGilleBhreac
Wim van 't Plasman

输出

注意:下面显示的只是上面输入的匹配字符串

Urxan Əbűlhəsənzadə
İsmət Jafarov
Şükür Hagverdiyev
Űmid Abdurrahimov
Ġerardo Seralta
Ċikku Paris
Hind ibn Sheik
Colop-U-Uichikin
Lażżru Role
Alaksiej Taraškievič
Petruso Husoǔski
Sumu-la-El
Valeh ßlÿsgÿroğlu
'Arab al-Rashayida
Tariq al-Hashimi
Nabeeh el-Mady
Tariq Al-Hashimi
Brian O'Conner
Maria da Silva
Maria Silva
Maria G. Silva
Maria McDuffy
Getúlio Dornelles Vargas
Maria das Flores
John Smith
John D'Largy
John Doe-Smith
John Doe Smith
Hector Sausage-Hausen
Mathias d'Arras
Martin Luther King Jr.
Ai Wong
Chao Chang
Alzbeta Bara
Marcos Assunção
Maria da Silva e Silva
Juscelino Kubitschek de Oliveira
Maria da Costa e Silva
Samuel Eto'o
María Antonieta de las Nieves
Eugène
Antòny de Homé April
àntony de Home ùpril
Antony de Home Aprìl
Pierre de l'Estache
Pierre de L'Estoile
Akihito
Nadine Schröder
Anna A. Møller
D. Pedro I
Pope Benedict XVI
Marsibil Ragnarsdóttir
Natanaël Morel
Isaac De la Croix
Jean-Michel Bozonnet
Qutaibah Mu'tazz Abadi
Rushd Jawna' Kassab
Khaldun Abdul-Qahhar Sabbag
'Awad Bashshar Asker
Al B. Zellweger
Gunnleif Snæ-Ulfsson
Käre Toresson
Sorli Ærnmundsson
Arnkel Øystæinsson
Ástríður Dórey
Åsmund Kåresson
Yahatti-Il
Ipqu-Annunitum
Nabu-zar-adan
Eskopas Cañaverri
Botolph of Langchester
Aelfhun the Cantrell
Fraco di Natale
Fraco Di Natale
Iván de Luca
Iván De Luca
Man'nah
Atabala Aüamusalü
Ramiz Ağasəfalu
Dadaş Aghakhanov
Fÿrxad Mübarizlı
Vaclaǔ Šupa
Yakiv Volacič
Flor Van Vaerenbergh
Flor van Vaerenbergh
Edwin van der Sar
Husein Ekmečić
Álvaro Guimarães Alencar
Phone U Yaza Arkar
Seocan MacGhille
X'wat'e Tlekadugovy
Albert-Jan Bootsveld
Maurits-jan Kuipers op den Kollenstaart
Elco ter Hoek
Robbert te Poele
Aad ten Have
'Ehu Kali
Ho'opa'a Loni
Aukanai'i Mahi'ai
Kalman ben Tal El
Żytomir Roszkowski
K'awai
Maol-Moire Mac'IlleBhuidh
Tòmas MacIlleChruim
Aindreas MacIllEathain
Eanruig MacGilleBhreac
Peadar MacGilleDhonaghart
Maolmhuire MacGill-Eain
Eanruig MacGilleBhreac
Wim van 't Plasman

说明

我使用了一个定义块来创建定义。您可以查看每个定义以了解其工作原理。一般来说,我使用\p{.},其中.被一些指向Unicode字符组的指针替换(即\p{L}是来自任何语言的任何字母——这在大多数正则表达式中都不起作用,但它确实允许正则表达式如果可用的话会更加简化,这就是我使用它的原因。

如果您需要任何其他解释,请随时问我,我会尽力而为,但是 regex101 应该能够解释您对 regex 的任何疑问。

【讨论】:

  • 不错!在 Regex101 上工作,稍后再检查。你知道 Excel Regex 5.5 是否接受 unicode 吗? \p{L}\p{Nl}
  • @danieltakeshi 不幸的是,我认为它不会接受任何这种正则表达式。毕竟,它是微软哈哈(他们喜欢重新发明*,并确保*是方形的,圆角,这样它就“与众不同”——有效,但无效)。但是您可以将其分解并根据我介绍的内容构建正则表达式(它与代码的构造方式密切相关,因此,假设您具有编码背景,您应该能够正确操作它)。我以我的方式呈现它,以便于理解(而不是冗长的 idkwhatitsays 正则表达式)
  • 另外,作为旁注,验证名称是个坏主意。我知道这是一个个人项目,但从不验证名称(您可以验证,例如,至少有 1 个字符并且它不是不可见的,但仅此而已)。请参阅how can i validate a name middle name and last name using regex in javapersonal names in a global application what to store 了解更多信息。