【问题标题】:JS Regex For Human Names用于人名的 JS 正则表达式
【发布时间】:2010-09-20 00:35:27
【问题描述】:

我正在寻找一个好的 JavaScript RegEx 来将名称转换为正确的大小写。例如:

John SMITH = John Smith

Mary O'SMITH = Mary O'Smith

E.t MCHYPHEN-SMITH = E.T McHyphen-Smith  

John Middlename SMITH = John Middlename SMITH

你明白了。

有人想出一个全面的解决方案吗?

【问题讨论】:

    标签: javascript regex string text


    【解决方案1】:

    Mark Summerfield 通过Lingua::EN::NameCase 完成了这方面的全面工作:

    KEITH               Keith
    LEIGH-WILLIAMS      Leigh-Williams
    MCCARTHY            McCarthy
    O'CALLAGHAN         O'Callaghan
    ST. JOHN            St. John
    VON STREIT          von Streit
    VAN DYKE            van Dyke
    AP LLWYD DAFYDD     ap Llwyd Dafydd
    henry viii          Henry VIII
    louis xiv           Louis XIV
    

    上面是用 Perl 编写的,但是它大量使用了正则表达式,所以你应该能够收集到一些好的技巧。

    这里是相关来源:

    sub nc {
    
        croak "Usage: nc [[\\]\$SCALAR]"
            if scalar @_ > 1 or ( ref $_[0] and ref $_[0] ne 'SCALAR' ) ;
    
        local( $_ ) = @_ if @_ ;
        $_ = ${$_} if ref( $_ ) ;           # Replace reference with value.
    
        $_ = lc ;                           # Lowercase the lot.
        s{ \b (\w)   }{\u$1}gox ;           # Uppercase first letter of every word.
        s{ (\'\w) \b }{\L$1}gox ;           # Lowercase 's.
    
        # Name case Mcs and Macs - taken straight from NameParse.pm incl. comments.
        # Exclude names with 1-2 letters after prefix like Mack, Macky, Mace
        # Exclude names ending in a,c,i,o, or j are typically Polish or Italian
    
        if ( /\bMac[A-Za-z]{2,}[^aciozj]\b/o or /\bMc/o ) {
            s/\b(Ma?c)([A-Za-z]+)/$1\u$2/go ;
    
            # Now correct for "Mac" exceptions
            s/\bMacEvicius/Macevicius/go ;  # Lithuanian
            s/\bMacHado/Machado/go ;        # Portuguese
            s/\bMacHar/Machar/go ;
            s/\bMacHin/Machin/go ;
            s/\bMacHlin/Machlin/go ;
            s/\bMacIas/Macias/go ;  
            s/\bMacIulis/Maciulis/go ;  
            s/\bMacKie/Mackie/go ;
            s/\bMacKle/Mackle/go ;
            s/\bMacKlin/Macklin/go ;
            s/\bMacQuarie/Macquarie/go ;
        s/\bMacOmber/Macomber/go ;
        s/\bMacIn/Macin/go ;
        s/\bMacKintosh/Mackintosh/go ;
        s/\bMacKen/Macken/go ;
        s/\bMacHen/Machen/go ;
        s/\bMacisaac/MacIsaac/go ;
        s/\bMacHiel/Machiel/go ;
        s/\bMacIol/Maciol/go ;
        s/\bMacKell/Mackell/go ;
        s/\bMacKlem/Macklem/go ;
        s/\bMacKrell/Mackrell/go ;
        s/\bMacLin/Maclin/go ;
        s/\bMacKey/Mackey/go ;
        s/\bMacKley/Mackley/go ;
        s/\bMacHell/Machell/go ;
        s/\bMacHon/Machon/go ;
        }
        s/Macmurdo/MacMurdo/go ;
    
        # Fixes for "son (daughter) of" etc. in various languages.
        s{ \b Al(?=\s+\w)  }{al}gox ;   # al Arabic or forename Al.
        s{ \b Ap        \b }{ap}gox ;       # ap Welsh.
        s{ \b Ben(?=\s+\w) }{ben}gox ;  # ben Hebrew or forename Ben.
        s{ \b Dell([ae])\b }{dell$1}gox ;   # della and delle Italian.
        s{ \b D([aeiu]) \b }{d$1}gox ;      # da, de, di Italian; du French.
        s{ \b De([lr])  \b }{de$1}gox ;     # del Italian; der Dutch/Flemish.
        s{ \b El        \b }{el}gox unless $SPANISH ;   # el Greek or El Spanish.
        s{ \b La        \b }{la}gox unless $SPANISH ;   # la French or La Spanish.
        s{ \b L([eo])   \b }{l$1}gox ;      # lo Italian; le French.
        s{ \b Van(?=\s+\w) }{van}gox ;  # van German or forename Van.
        s{ \b Von       \b }{von}gox ;  # von Dutch/Flemish
    
        # Fixes for roman numeral names, e.g. Henry VIII, up to 89, LXXXIX
        s{ \b ( (?: [Xx]{1,3} | [Xx][Ll]   | [Ll][Xx]{0,3} )?
                (?: [Ii]{1,3} | [Ii][VvXx] | [Vv][Ii]{0,3} )? ) \b }{\U$1}gox ;
    
        $_ ;
    }
    

    【讨论】:

      【解决方案2】:

      懦夫!....这是我的第二次尝试。处理“John SMITH”、“Mary O'SMITH”、“John Middlename SMITH”、“E.t MCHYPHEN-SMITH”和“JoHn-JOE MacDoNAld”

      Regex fixnames = new Regex("(Ma?C)?(\w)(\w*)(\W*)");
      string newName = fixnames.Replace(badName, NameFixer);
      
      
      static public string NameFixer(Match match) 
      {
          string mc = "";
          if (match.Groups[1].Captures.Count > 0)
          {
              if (match.Groups[1].Captures[0].Length == 3)
                  mc = "Mac";
              else
                  mc = "Mc";
          }
      
          return 
             mc
            +match.Groups[2].Captures[0].Value.ToUpper()
            +match.Groups[3].Captures[0].Value.ToLower()
            +match.Groups[4].Captures[0].Value;
      }
      

      注意:当我意识到您想要一个 Javascript 解决方案而不是 .NET 解决方案时,我已经有太多好笑的事情了......

      【讨论】:

      • 这不是 JavaScript ;) 而且,这真的不是单独的正则表达式的工作 - 结合词法解析,你可以获得 90% 的系统,我认为。
      【解决方案3】:

      这样的?

      function fix_name(name) {
          var replacer = function (whole,prefix,word) {
              ret = [];
              if (prefix) {
                  ret.push(prefix.charAt(0).toUpperCase());
                  ret.push(prefix.substr(1).toLowerCase());
              }
              ret.push(word.charAt(0).toUpperCase());
              ret.push(word.substr(1).toLowerCase());
              return ret.join('');
          }
          var pattern = /\b(ma?c)?([a-z]+)/ig;
          return name.replace(pattern, replacer);
      }
      

      【讨论】:

        【解决方案4】:

        同意它永远不会完美,但希望得到最常见的情况。这几乎是驼峰式的任何“单词”,并且我猜想将连字符和撇号处理为空格。

        【讨论】:

          【解决方案5】:

          不幸的是,有太多不同的名称格式无法正确执行此操作。约翰-乔·麦克唐纳总是令人讨厌!

          【讨论】:

          • 你说得对!他还是小学时的那个恶棍!
          • 你应该看看他对 Lilly-Anne da Silva 的书包做了什么;真是个小鬼!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多