2014-02-23 14 views
11

Ich habe mir selbst eine Funktion geschrieben, um eine Zeichenkette in eine Abkürzung umzuwandeln, und sie ist momentan ziemlich lang und es wird zwischen Groß- und Kleinschreibung unterschieden.JavaScript-Funktion verkürzen

Ich brauche eine Möglichkeit, es zu verkürzen, damit es 100% der Zeit funktioniert. Momentan verschraubt es sich, wenn eines der aufspaltenden Wörter ein Großbuchstabe hat, wenn ein Wort in einem aufspaltenden Wort endet.

Meine spaltenden Wörter sind im Grunde die Wörter, die ich entferne (wie die meisten Unternehmen und solche enthalten sie nicht). Dazu gehören:

  • und
  • von
  • die
  • für
  • zu

Auch die Art, wie ich sie habe Entfernen Split mit und verbinden (str.split('and ').join('')), die für mich scheint nicht der einfachste Weg.

Abgesehen von diesen Problemen funktioniert es gut. Könnte mir jemand helfen, die Funktion zu verkleinern und die Probleme zu beheben? Vielen Dank.

Funktion:

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('.'); 
} 

Ausgänge auf Getestet Firmen

 
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

Wie wäre es stattdessen mit einem Ersatz für reguläre Ausdrücke? Sie können den Modifizierer "i" verwenden, um die Groß- und Kleinschreibung zu ignorieren. – Barmar

+0

Können Sie mir ein Beispiel zeigen? Ich habe noch nie zuvor Regex benutzt. @thefourtheye Danke für die Bearbeitung, habe vergessen, das zu tun, bevor ich gepostet habe. – Spedwards

+0

Erweitern Sie den String-Prototyp dafür nicht. Das Erweitern von nativen Prototypen ist in JavaScript generell sehr verpönt. Habe einfach eine normale Funktion - nichts falsch daran. –

Antwort

8

Eine noch kürzere:

str.replace(/(and|of|the|for|to)(|$)/gi, "").replace(/(.).+?(\s|$)/g, "$1."); 

Um sicherzustellen, dass es aktiviert wird Sie .toUpperCase am Ende tun können.

(.)  //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" 

ist es in einer Regex machen lassen!

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. 

Dies sollte in der Theorie, decken alle legit Namen. Für Namen mit Präposition (n) am Ende, können Sie technisch dies tun:

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

Aber das ist deutlich länger als die eines mit zwei replace s und diese besiegt seinen Zweck erfüllt.

+0

Derek, erklären Sie die Regex für den letzten Teil: /(.).+?(\s|$)/, bitte –

+0

Dies gilt nicht, wenn die ausgeschlossenes Wort ist am Ende der Zeichenfolge und hat eine extra Periode am Ende;) – nderscore

+0

@nderscore - Es tut jetzt –

2

warum nicht versuchen, etwas Ähnliches statt?

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

Ansonsten ist der Rest in Ordnung scheint

12

Ich denke, ein Ansatz, wie diese besser funktionieren könnte:

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 
}; 

und hier ist eine Aufschlüsselung des regulären Ausdrucks:

/ 
    \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 

Und Hier ist eine alternative Methode, die einen weniger komplizierten regulären Ausdruck hat:

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 
}; 

Und regex Zusammenbruch:

/ 
    ^     // 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

Warum nicht nur '.replace (/ (.). +? (\ S | $)/g," $ 1 ")' –

+0

@Derek 朕 會 功夫 das wäre auch eine akzeptable Möglichkeit, nur den ersten Buchstaben zu bekommen, aber es kapitalisiert nicht. – nderscore

+1

Ja, aber Sie können immer das Ergebnis und das Ende groß schreiben;) –

4

Sie können auch reduzieren Sie verwenden. Was Sie tun, ist im Wesentlichen eine Reduktion der Zeichenfolge Abkürzung -

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' würde scheinen, der Weg zu gehen, aber Sie könnten dies verbessern, indem Sie die ECMA5' indexOf' anstatt Ihre Regex und haben eine Ausschlussliste. Und umgekehrt 'toUpperCase(). CharAt (0)' hätte etwas weniger Arbeit. – Xotic750

+0

wie würde es verbessern? Leistung weise? –

+0

Leistung ist nicht so sehr das Problem, mehr Vermeidung dieser Art von Sache ist. http://jsfiddle.net/Xotic750/AVXbg/ – Xotic750

2

einfach ersetzen eine Zeichenfolge in folgender Weise:

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

Dies würde auch die Frage eines der Spalt Worte lösen am Ende jedes Hauptwort zu sein.

Für alle Splitting Wörter am Anfang der Zeichenfolge zu entfernen, machen Sie einfach folgendes:

var pos = a.search(/and |of |the |for |to /i); 
if (pos == 0) 
    //remove that word 
2

Eine mögliche Lösung mit 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')); 

Ausgabe

S.S.S. 
N.A.S.A. 
N.R.M.A. 
R.S.P.C.A. 

Auf jsFiddle

Sie könnten wahrscheinlich die split regex (/[^\w]/) verbessern, um weitere Kuriositäten zu behandeln. Oder teilen Sie einfach Whitespace /\s/ und fügen Sie sie der Ausschlussliste hinzu.

Verwandte Themen