Сократить функцию Javascript
Я написал себе функцию, чтобы превратить строку в аббревиатуру, и в настоящее время она довольно длинная и чувствительна к регистру.
Мне нужно укоротить его, чтобы он работал в 100% случаев. В настоящее время он завинчивается, если одно из слов расщепления имеет капитал, если слово заканчивается словом.
Мои разделительные слова - это в основном слова, которые я удаляю (поскольку большинство компаний и их не включают). К ним относятся:
Кроме того, способ, которым я их удаляю, - использовать split и join (str.split('and ').join('')
), который мне кажется не самым простым способом.
Помимо этих проблем, он отлично работает. Может ли кто-нибудь помочь мне сгладить функцию и исправить проблемы? Спасибо.
Функция:
String.prototype.toAbbrev = function () {
var s = [];
var a = this.split('and ').join('').split('of ').join('').split('the').join('').split('for ').join('').split('to ').join('').split(' ');
for (var i = 1; i < a.length + 1; i++) {
s.push(a[i - 1].charAt(0).toUpperCase());
}
return s.join('.');
}
Выходы на тестируемые компании
The National Aeronautics and Space Administration -> N.A.S.A
The National Roads and Motorists' Association -> N.R.M.A
Royal Society for the Prevention of Cruelty to Animals -> R.S.P.C.A
Ответы
Ответ 1
Еще более короткий:
str.replace(/(and|of|the|for|to)( |$)/gi, "").replace(/(.).+?(\s|$)/g, "$1.");
Чтобы убедиться, что он заглавный, вы можете сделать .toUpperCase
в конце.
(.) //selects the first character
.+ //matches the rest of the characters
? //? indicates a lazy match
(\s|$) //match a space or the end
$1. //means "the first selected match plus a dot"
Пусть превращается в одно Regex!
str.replace(/((and|of|the|for|to) )*(.).+?(\s|$)/ig, "$3.");
"Royal Society for the Prevention of Cruelty to Animals"
.replace(/((and|of|the|for|to) )*(.).+?(\s|$)/ig, "$3.");
//R.S.P.C.A
"Josie and the Pussycats"
.replace(/((and|of|the|for|to) )*(.).+?(\s|$)/ig, "$3.");
//J.P.
Это должно теоретически охватывать все законные имена. Для имен с предлогами (именами) в конце вы можете технически сделать это:
.replace(/((and|of|the|for|to) )*(.).+?(\s|$)((and|of|the|for|to) ?)*/ig, "$3.")
Но это явно больше, чем тот, у которого два replace
, и это побеждает его цель.
Ответ 2
Я думаю, что такой подход может работать лучше:
var toAbbrev = function(str){
return str.replace(/\b(?:and|of|the|for|to)(?: |$)/gi,''). // remove all occurances of ignored words
split(' '). // split into words by spaces
map(function(x){
return x.charAt(0).toUpperCase(); // change each word into its first letter capitalized
}).
join('.'); // join with periods
};
и здесь пробой регулярного выражения:
/
\b // word boundary
(?:and|of|the|for|to) // non-capturing group. matches and/of/the/for/to
(?: |$) // non-capturing group. matches space or end of string
/gi // flags: g = global (match all), i = case-insensitive
И здесь альтернативный метод, который имеет менее сложное регулярное выражение:
var toAbbrev = function(str){
return str.split(' '). // split into words
filter(function(x){
return !/^(?:and|of|the|for|to)$/i.test(x); // filter out excluded words
}).
map(function(x){
return x.charAt(0).toUpperCase(); // convert to first letter, captialized
}).
join('.'); // join with periods
};
И разбивка регулярных выражений:
/
^ // start of string
(?:and|of|the|for|to) // non-capturing group. matches and/of/the/for/to
$ // end of string
/i // flags: i = case-insensitive
Ответ 3
Вы также можете сделать это, используя сокращение. То, что вы делаете, по сути сводится к сокращению строки до аббревиатуры -
str.split(' ').reduce(function(preV, curV, index) {
if(!/^(and|of|the|for|to)$/.test(curV.toLowerCase())) {
return preV + curV.toUpperCase().charAt(0) + '.';
}
return preV;
}, '');
Ответ 4
почему бы не попробовать что-то вроде этого?
var a=this.replace(/and |of |the |for |to /gi, '').split(' ');
В противном случае остальное кажется прекрасным
Ответ 5
Просто замените строку следующим образом:
var a = this.replace(/ and | of | the | for | to /gi, ' ').split(' ');
Это также разрешит проблему одного из слов расщепления, находящихся в конце любого основного слова.
Для удаления любых разделительных слов в начале строки просто выполните следующие действия:
var pos = a.search(/and |of |the |for |to /i);
if (pos == 0)
//remove that word
Ответ 6
Возможное решение с использованием ECMA5
Javascript
var toAbbrev = (function (ignore) {
return function toAbbrev(myString) {
return myString.split(/[^\w]/).reduce(function (acc, word) {
if (word && ignore.indexOf(word.toLowerCase()) === -1) {
acc += word.charAt(0).toUpperCase() + '.';
}
return acc;
}, '');
};
}(['and', 'of', 'the', 'for', 'to']));
console.log(toAbbrev('The Silica & Sand Society'));
console.log(toAbbrev('The National Aeronautics and Space Administration'));
console.log(toAbbrev('The National Roads and Motorists\' Association'));
console.log(toAbbrev('Royal Society for the Prevention of Cruelty to Animals'));
Выход
S.S.S.
N.A.S.A.
N.R.M.A.
R.S.P.C.A.
Вкл jsFiddle
Возможно, вы могли бы улучшить регулярное выражение split
(/[^\w]/
) для обработки дополнительных странностей. Или просто разделите пробелы /\s/
и добавьте в список исключений.