我有一个包含大量名称的列表,我需要将其转换为字母数字用户名。我想要做的是取名称,删除任何非字母数字值,并将其转换为删除字符的标题情况。例如:
johnson -> Johnson
Van Halen -> VanHalen
Torres-hernandez -> TorresHernandez
Rafael van der vaart -> RafaelVanDerVaart
这可以用正则表达式完成吗?
答案 0 :(得分:3)
使用一些字符串操作,您可以相当简单地完成此操作。
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();
}
答案 1 :(得分:2)
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' ]
答案 2 :(得分:1)
您可以使用简单的正则表达式执行此操作:
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's answer,与他自己非常相似。不同之处在于我的版本使用数组操作而不是for
循环,并使用filter
来处理开头或其中的字符串错误的字符串。
我在正则表达式中使用\w
和\W
个特殊文字,分别等于[A-Za-z0-9_]
和[^A-Za-z0-9_]
(see JavaScript Regular Expressions Docs)。如果您不希望将_
计为字母数字字符,则应将\w
和\W
替换为要匹配的确切字符集(例如[A-Za-z0-9]
和{{1 }})。