Javascript 将单个字段分为名称、第二个名称和姓氏
如何将全名拆分为单名、中名和姓氏 显然,不可能涵盖所有可能性。我只想要一条规则:如果单词后面有来自3个字母或更少的其他单词,它必须与下一个单词连接 此外,我假设全名有3个或更多单词 我真的不知道该怎么开始 例如: 约翰·马丁·杰克逊:Javascript 将单个字段分为名称、第二个名称和姓氏,javascript,split,Javascript,Split,如何将全名拆分为单名、中名和姓氏 显然,不可能涵盖所有可能性。我只想要一条规则:如果单词后面有来自3个字母或更少的其他单词,它必须与下一个单词连接 此外,我假设全名有3个或更多单词 我真的不知道该怎么开始 例如: 约翰·马丁·杰克逊: 名字1:约翰 姓名2:马丁 姓名3:杰克逊 史蒂文·庞塞·德莱昂·普雷斯利 姓名1:史蒂文 姓名2:庞塞德莱昂 名字3:普雷斯利 迈克尔·德拉罗莎·马丁·杰克逊: 姓名1:迈克尔·德拉罗萨 姓名2:马丁 姓名3:杰克逊 :S一个非常花哨的正则表达式可以
- 名字1:约翰
- 姓名2:马丁
- 姓名3:杰克逊
- 姓名1:史蒂文
- 姓名2:庞塞德莱昂
- 名字3:普雷斯利
- 姓名1:迈克尔·德拉罗萨
- 姓名2:马丁
- 姓名3:杰克逊
: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+)*)$/
要使其匹配没有中间名的人,请将其设置为可选:
/^(\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
var name=input.split(/s+/);
if(name.length<2)
返回;//只有一个单词的特殊情况处理
var-short=0;
对于(var i=names.length-2;i>=0;i--){
//从倒数第二开始,我希望名字不会以短名字结尾
if(名称[i]。长度<4){
short++;
}否则,如果(短){
名称[i]+=“”+名称.拼接(i+1,short+1).join(“”);
short=0;
}
}
返回名称;//至少有一个名称的数组
一个非常花哨的正则表达式可以做到这一点。要匹配一个名称,请使用
/\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
var name=input.split(/s+/);
if(name.length<2)
返回;//只有一个单词的特殊情况处理
var-short=0;
对于(var i=names.length-2;i>=0;i--){
//从倒数第二开始,我希望名字不会以短名字结尾
if(名称[i]。长度<4){
short++;
}否则,如果(短){
名称[i]+=“”+名称.拼接(i+1,short+1).join(“”);
short=0;
}
}
返回名称;//至少有一个名称的数组
像这样的东西怎么样
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;
}
函数拆分\u名称(名称){
var parts=name.split(“”);
var num_parts=parts.length;
var i=0;
变量名称=[];
_界()中的函数{
返回i
JSFiddle:
这不是有史以来性能最好的算法。Regex大师可能在一行中也能做到这一点,但至少这样我们凡人都能读懂。(更新:我认为Bergi就是这样一位正则表达式大师。)
它与您描述的大致相同,但您必须根据自己的需要进行调整。例如,它返回一个数组,其中包含找到的尽可能多的“子名称”。因此,如果找不到中间名,它将返回长度为2的数组。另一方面,它可能会找到3个以上的名称。你必须考虑如何处理这个问题。像这样的事情怎么样
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;
}
函数拆分\u名称(名称){
var parts=name.split(“”);
var num_parts=parts.length;
var i=0;
变量名称=[];
_界()中的函数{
返回i
JSFiddle:
这不是有史以来性能最好的算法。Regex大师可能在一行中也能做到这一点,但至少这样我们凡人都能读懂。(更新:我认为Bergi就是这样一位正则表达式大师。)
它与您描述的大致相同,但您必须根据自己的需要进行调整。例如,它返回一个数组,其中包含找到的尽可能多的“子名称”。因此,如果找不到中间名,它将返回长度为2的数组。另一方面,它可能会找到3个以上的名称。您必须考虑如何处理该问题。这里是另一个工作函数
编辑:坏链接这里是另一个工作功能
编辑:坏链接我认识一个叫迈克尔·哈里斯·希顿·琼斯·帕特里克的家伙。(我想他是波士顿的一名建筑师。)没有明确的模式,为什么我们不能