2014-02-23 76 views
11

我给自己写了一个函数,将字符串转换成缩写,目前它相当长,并且区分大小写。缩短的JavaScript功能

我需要一种方法缩短它,所以它的工作时间100%。目前,如果其中一个拆分单词有大写字母,如果一个单词以拆分单词结尾,就会出现问题。

我拆分的单词基本上是我删除的单词(因为大多数公司并不包括它们)。它们包括:

此外,我除去他们的方法是使用分割和结合​​(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 
+5

如何使用正则表达式替换?你可以使用'i'修饰符使其不区分大小写。 – Barmar

+0

你能告诉我一个例子吗?我从来没有使用过正则表达式。 @thefourtheye感谢您的编辑,忘记之前我发布。 – Spedwards

+0

不要为此扩展字符串原型。在javascript中扩展原生原型通常非常令人不悦。只要有一个正常的功能 - 没有错。 –

回答

8

更短的一个:

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" 

让我们把它变成一个正则表达式!

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. 

这应,在理论上,覆盖所有合法的名称。对于末介词(S)的名称,您可以技术上做到这一点:

.replace(/((and|of|the|for|to))*(.).+?(\s|$)((and|of|the|for|to) ?)*/ig, "$3.") 

但是,这是一个比两个replace小号要长,这违背了它的目的。

+0

德里克,解释正则表达式的后半部分:/(.).+?(\s|$)/,请 –

+0

这不占,如果排除字在字符串的末尾,并在末尾有一个额外的句点;) – nderscore

+0

@nderscore - 现在确实 –

2

为什么不尝试这样的事情呢?

var a=this.replace(/and |of |the |for |to /gi, '').split(' '); 

否则其余似乎罚款

12

我觉得这样的做法可能会更好地工作:

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 
+0

为什么不只是'.replace(/(。)。+?(\ s | $)/ g,“$ 1”)' –

+0

@Derek?会功夫,这也是一个可以接受的方式来得到第一个字母,但它不会大写。 – nderscore

+1

是的,但你总是可以大写结果和结束;) –

4

你也可以做它用减少。你在做什么本质上是一个还原的字符串来缩写 -

str.split(' ').reduce(function(preV, curV, index) { 
    if(!/^(and|of|the|for|to)$/.test(curV.toLowerCase())) { 
     return preV + curV.toUpperCase().charAt(0) + '.'; 
    } 
    return preV; 
}, ''); 
+0

'reduce'似乎是一条路要走,但你可以通过使用ECMA5'indexOf'而不是你的正则表达式并且有一个排除列表来改善这个问题。并且反转'toUpperCase()。charAt(0)'会少一点工作。 – Xotic750

+0

它会如何改善?性能明智吗? –

+0

表现不是问题,更多的是避免这种事情。 http://jsfiddle.net/Xotic750/AVXbg/ – Xotic750

2

只是做一个字符串,以下列方式取代:

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 
2

使用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/并添加到排除列表中。