2014-02-23 131 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/並添加到排除列表中。