我有一个包含一堆名称的列表,我需要将其转换为字母数字用户名。我想做的是取名字,删除任何非字母数字值并将其转换为删除字符的标题大小写。例如:
johnson -> Johnson
Van Halen -> VanHalen
Torres-hernandez -> TorresHernandez
Rafael van der vaart -> RafaelVanDerVaart
这可以用正则表达式完成吗?
我有一个包含一堆名称的列表,我需要将其转换为字母数字用户名。我想做的是取名字,删除任何非字母数字值并将其转换为删除字符的标题大小写。例如:
johnson -> Johnson
Van Halen -> VanHalen
Torres-hernandez -> TorresHernandez
Rafael van der vaart -> RafaelVanDerVaart
这可以用正则表达式完成吗?
使用一些字符串操作,您可以相当简单地做到这一点。
var name = "Torres-hernandez", i, part, out = "";
parts = name.split(/[^a-z0-9]+/gi);
for (i=0; part = parts[i++];) {
out += part[0].toUpperCase() + part.slice(1).toLowerCase();
}
var names = [
'johnson',
'Van Halen',
'Torres-hernandez',
'Rafael van der vaart'
]
for (var i = 0; i < names.length; i++) {
names[i] = names[i].replace(/(\W|^)(\w)/g, function(match) {
return match.substr(-1).toUpperCase();
});
}
console.log(names);
印刷
[ 'Johnson', 'VanHalen', 'TorresHernandez', 'RafaelVanDerVaart' ]
你可以用简单的正则表达式来做到这一点:
var titleCase = function(s) {
return s.toLowerCase().replace(/(?:^|\W)+(\w|$)/g, function(match, tail) {
return tail.toUpperCase();
});
};
此处的正则表达式/(?:^|\W)+(\w|$)/g捕获从前一个单词的开头到应该大写的新单词的第一个字母的子字符串。
它捕获整个匹配并将其替换为大写的最后一个字符tail。
如果您的字符串以错误字符(例如空格)结尾,那么它也会被捕获,但taild在这种情况下将是一个空字符串:
' toRReS $#@%^! heRnAndeZ -++--=-=' -> 'TorresHernandez'
让我们检查一下我的正则表达式:
(^|\W)+(...)+-非字母数字字符的序列\W或字符串的开头,^后面可以跟任意数量的非字母数字字符。它应该至少包含一个字符,除非它是字符串的开头,在这种情况下它可能为空。(?:^|\W)+- 同样的事情,但它不会因为?:. 我们并不真正关心这部分,只是想剥离它。(\w|$)- 任何字母数字字符\w或字符串的结尾$。这部分将被缓存并放入tail变量中。更新如果正则表达式让你感到困惑,你可以对字符串和数组操作做同样的事情:
var titleCase = function(str) {
return str.split(/\W+/g)
.filter(function(s) {
return s.length > 0;
}).map(function(s) {
return s[0].toUpperCase() + s.slice(1).toLowerCase();
}).join('');
};
这个解决方案的灵感来自FakeRainBrigand 的回答,与他自己的非常相似。不同之处在于我的版本使用数组操作而不是for循环,并用于filter处理开头或 and 处有坏字符的字符串。
我在我的正则表达式中使用了\w和\W特殊的文字,它们分别等于[A-Za-z0-9_]和[^A-Za-z0-9_](参见 JavaScript 正则表达式文档)。如果您不想_被算作字母数字字符,您应该用要匹配的确切字符集(例如and )替换\wand 。\W[A-Za-z0-9][^A-Za-z0-9]