2016-11-13 4 views
0

Ich bin auf der Suche nach einem regulären Ausdruck, der in der Lage, Wörter n durch n übereinstimmen. Lassen Sie uns n := 2 sagen, es ergäbe:Regexp, um Wörter zwei mal zwei (oder n von n)

Lorem ipsum dolor sit amet, consectetur adipiscing elit

Lorem ipsum, ipsum dolor, dolor sit, sit amet (hier das Komma bemerken), consectetur adipiscing, adipiscing elit.

Ich habe versucht, \b für Wortgrenzen ohne Erfolg zu verwenden. Ich bin wirklich verloren zu versuchen, eine Regex zu finden, die mir n Worte geben kann ... /\b(\w+)\b(\w+)\b/i kann es nicht schneiden, und sogar mehrere Kombinationen ausprobiert.

+0

Mögliches Duplikat von [Reguläre Ausdrücke lernen] (http://stackoverflow.com/questions/4736/learning-regular-expressions) – Biffen

+0

@Biffen Wie ist es ein Duplikat dieser Frage? –

+0

Dies ist im Grunde eine * Frage-mir-ein-Regex * 'Frage'. Sie sind alle Duplikate (in gewisser Weise) davon. – Biffen

Antwort

0

Reguläre Ausdrücke sind nicht wirklich das, was Sie brauchen hier, anders als die aufzuspalten Eingabe in Worte. Das Problem ist, dass dieses Problem beinhaltet Überlappung Teilstrings, die regexp nicht sehr gut ist, vor allem die JavaScript-Geschmack. Stattdessen brechen Sie einfach die Eingabe in Wörter und ein schnelles Stück JavaScript generiert die "N-Gramme" (was der korrekte Ausdruck für Ihre N-Wort-Gruppen ist).

const input = "Lorem ipsum dolor sit amet, consectetur adipiscing elit"; 
 

 
// From an array of words, generate n-grams. 
 
function ngrams(words, n) { 
 
    const results = []; 
 

 
    for (let i = 0; i < words.length - n + 1; i++) 
 
    results.push(words.slice(i, i + n)); 
 

 
    return results; 
 
} 
 

 
console.log(ngrams(input.match(/\w+./g), 2));

0

eine Wortgrenze \b nicht verbrauchen alle Zeichen, es ist eine Null-Breite Behauptung, und nur behauptet die Position zwischen einem Wort und Nicht-Wort-Zeichen und zwischen Beginn der Zeichenfolge und einer Wort char und zwischen einem Wort Zeichen und Ende der Zeichenfolge.

Sie müssen verwenden \s+ zu Leerzeichen zwischen den Wörtern verbrauchen, und verwenden Sie in einem positiven Look-Ahead-Technik erfassen überlappende Übereinstimmungen zu erhalten:

var n = 2; 
 
var s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit"; 
 
var re = new RegExp("(?=(\\b\\w+(?:\\s+\\w+){" + (n-1) + "}\\b))", "g"); 
 
var res = [], m; 
 
while ((m=re.exec(s)) !== null) { // Iterating through matches 
 
if (m.index === re.lastIndex) { // This is necessary to avoid 
 
     re.lastIndex++;   // infinite loops with 
 
}        // zero-width matches 
 
res.push(m[1]);     // Collecting the results (group 1 values) 
 
} 
 
console.log(res);

Das endgültige Muster dynamisch aufgebaut werden Da Sie eine Variable an die Regex übergeben müssen, benötigen Sie eine RegExp Konstruktornotation. Es sieht wie

/(?=(\b\w+(?:\s+\w+){1}\b))/g 

Und es wird alle Standorte in der Zeichenfolge finden, die mit der folgenden Reihenfolge eingehalten werden:

  • \b - eine Wortgrenze
  • \w+ - 1 oder mehr Wort Zeichen
  • (?:\s+\w+){n}-n Sequenzen:
    • \s+ - 1 oder mehr Whitespaces
    • \w+ - 1 oder mehr Wort Zeichen
  • \b - eine Hinterwortgrenze
+0

Dies scheint wie massiver Overkill. –

+0

Eine funktionierende, erweiterbare Lösung ist niemals ein Overkill. –

-1

keine reine regex Lösung, aber es funktioniert und ist leicht zu lesen und zu verstehen:

let input = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'; 
let matches = input.match(/(\w+,? \w+)/g) 
    .map(str => str.replace(',', '')); 

console.log(matches) // ['Lorem ipsum', 'dolor sit', 'amet consectetur', 'adipiscing elit'] 

Achtung: Nicht für keine Übereinstimmungen überprüfen (match() gibt null zurück)

Verwandte Themen