将单个字段分隔为名称,第二个名称和姓氏

时间:2012-08-02 22:05:14

标签: javascript split

如何将全名拆分为单个,中等和姓氏?

显然,不可能涵盖所有可能性。我只想要一条规则:如果在单词后面有3个字母或更少的单词,它必须与下一个单词连接。

另外,我假设全名有3个字或更多。

我真的不知道如何开始。

例如:

John Martin Jackson:

  • name1:John
  • name2:Martin
  • name3:杰克逊

Steven Ponce de Leon Presley

  • name1:Steven
  • name2:Ponce de Leon
  • name3:Presley

Michael de la Rosa Martin Jackson:

  • name1:Michael de la Rosa
  • name2:Martin
  • name3:杰克逊

:S

3 个答案:

答案 0 :(得分:3)

一个非常花哨的正则表达式可以做到这一点。要匹配一个名称,请使用

/\S+((\s+\S{1,3})+\s+\S+)*/

然后,将其中三个与不匹配的组合在一起,但每个组合在一起,由空格连接:

/^(\S+(?:(?:\s+\S{1,3})+\s+\S+)*)\s+(\S+(?:(?:\s+\S{1,3})+\s+\S+)*)\s+(\S+(?:(?:\s+\S{1,3})+\s+\S+)*)$/

要使其与没有中间名的人匹配,请将其设为可选:

/^(\S+(?:(?:\s+\S{1,3})+\s+\S+)*)(?:\s+(\S+(?:(?:\s+\S{1,3})+\s+\S+)*))?\s+(\S+(?:(?:\s+\S{1,3})+\s+\S+)*)$/

更新:不要试图在一个正则表达式中匹配全名。只需使用带有全局标志的第一个(简单)正则表达式:

> "Steven Ponce de Leon Presley".match(/\S+((\s+\S{1,3})+\s+\S+)*/g)
["Steven", "Ponce de Leon", "Presley"]

说明:

/
 \S+      match a word
 (         followed by any number of
  (         at least one
   \s+       whitespace-separated
   \S{1,3}   up-to-three-letters word
  )+
  \s+       and a whitespace-separated
  \S+       word
 )*
/g

但是,我认为一个带有一些字符串和数组函数的算法会使发生的事情更加清晰,并允许更多的匹配过程自定义:

var names = input.split(/s+/);
if (names.length < 2)
    return; // special case handling for only one word
var short = 0;
for (var i=names.length-2; i>=0; i--) {
    // starting at the second-to-last, I expect names not to end with a short one
    if (names[i].length < 4) {
        short++;
    } else if (short) {
        names[i] += " "+names.splice(i+1, short+1).join(" ");
        short = 0;
    }
}
return names; // an Array with at least one name

答案 1 :(得分:1)

这样的事情怎么样?

function split_name(name) {
    var parts = name.split(" ");
    var num_parts = parts.length;
    var i = 0;
    var names = [];

    function in_bounds() {
        return i < num_parts;
    }
    function next_part() {
        i += 1;
        return parts[i - 1];
    }
    function part_is_short() {
        return parts[i].length < 4;
    }
    function last_part_was_short() {
        return parts[i-1].length < 4;
    }
    function next_name() {
        var name = next_part();
        if (in_bounds() && part_is_short()) {
            name += " " + next_part();
            while(in_bounds() && last_part_was_short()) {
                name += " " + next_part();
            }
        }
        return name;
    }

    while (in_bounds()) {
        names.push(next_name());
    }

    return names;
}

JSFiddle:http://jsfiddle.net/nLe7S/2/

这不是有史以来最高效的算法。正则表达式专家可能会在同一行中做同样的事情,但至少这种方式对我们凡人来说是可读的。 更新:我认为Bergi has just proven himself是这样的正则表达式大师。:)

它大致完成了你所描述的内容,但你必须根据自己的需要进行调整。例如,它返回一个包含所查找的“子名称”的数组。因此,如果它找不到中间名,它将返回一个长度为2的数组。另一方面,它可能会找到3个以上的名字。你必须考虑如何处理它。

答案 2 :(得分:1)

这是另一个工作函数http://jsfiddle.net/xPzEs/7/

编辑:错误链接