2015-07-29 14 views
6

Więc robię to program do analizowania drgać czat, i zastanawiam się, czy jest jakiś sposób mogę używać regex do analizowania następujących do pożądanego rezultatu:RegExp wykrywa wiele jednoliterowych wystąpień z rzędu?

"f o o b a r" into "foobar"

Dotychczas kodu mam to /(?:(\w)\s){3,}/g i działa to do pewnego stopnia, ale Rozważmy następującą sytuację:

"FrankerZ R I O T FrankerZ" przechwytuje „T” (ostatnia litera w "R I O T") i wybiera "Z R I O T"

Co miałbym do tego celu jest dowiedzieć się, jak wykryć, czy jest jedna litera z spacją przed i po nim, i jeśli są co najmniej 3 z nich z rzędu (więc "test a b test" nie jest wybrany jako ab, tylko przechwytuje, jeśli są 3+)

Każda pomoc? Dzięki!

Odpowiedz

1

Dziękuję Sam Burns za sugestię użycia \ b. Co działa dla mnie było:

/\b((?:\w ?\b){3,})/g

Byłoby to wybierz następujące:

H Y P E z FrankerZ H Y P E FrankerZ, i f o o b a r (nie kończą lub zaczynają się od znaku spacji, dawał mi zagadnienia jak dobrze)

Określanie literowej przestrzeni " " zamiast nazwy \s było również ważne dla uniknięcia łamania linii i innych przypadków, kiedy chciałem tylko t o najpierw sprawdź tylko znak spacji.

Aby zastąpić go bez spacji, po prostu wykonam .replace(" ",""), aby uzyskać dokładny wynik, jaki chciałem. Jeszcze raz dziękuję za pomoc :) każdy

-1

Zamiast używać regex, można zrobić funkcję, która pobiera ciąg, dzieli ciąg w przestrzeni następnie zwraca wszystkie pojedyncze litery

function findSingleLetters(string){ 
     var split = string.split(" "); 
     var word= []; 
     for(int i=0;i<split.length; i++){ 
      if(split[i].length==1){ 
       word.push(split[i]); 
      } 
     } 
     return word.toString().replace(/,/g,""); //join the word array and replace all the remaining commas(,) 
    } 
+0

Czy nie dałoby mi to wszystkich pojedynczych listów? Co jeśli ktoś powie "to jest test, RIOT" ', to da ci' "a, r, i, o, t" ', dlatego chcę, aby zaczął on przechwytywać, gdy jest 3 + wystąpień pojedynczych liter z rzędu. Masz pomysł, jak to uwzględnić w kodzie, który napisałeś? – Flipybitz

-1

\b jest zero-szerokość twierdzenie, że pasuje do szczeliny pomiędzy słowem czarterowym a nie-słowem. Na przykład /\b\w\s/ pasuje do R w rZ R I, ale nie Z: Z nie następuje po "dzieleniu wyrazów" ani przełączaniu między wyrazami i znakami innymi niż słowa. Spróbuj wstawić to na początku wyrażenia regularnego, aby pokazać, że nie chcesz, aby zaczęło pasować w środku słowa.

+0

Dziękujemy! To było dokładnie to, czego potrzebowałem, chciałbym + powtórzyć, ale nie mam wystarczająco dużo reputacji, aby to zrobić. Napiszę na to moją odpowiedź.Jeszcze raz dziękuję :) – Flipybitz

3

Spróbuj tego wzoru: /(?:\b\w(?:\s|$)){3,}/g

używa metaznaku brzegowy słowo \b więc masz prawidłowe dopasowanie całe słowo zamiast częściowego mecz widziałeś z FrankerZ. Ponadto, bit \s|$ adresuje ostatnią literę traconą, gdy nie ma miejsca po niej, np. "T" w R I O T.

przykład:

var inputs = [ 
    "R I", 
    "R I O T", 
    "FrankerZ R I O T FrankerZ", 
    "f o o b a r" 
]; 

var re = /(?:\b\w(?:\s|$)){3,}/g; 

inputs.forEach(function(s) { 
    var match = s.match(re); 
    if (match) { 
    var result = match[0].replace(/\s/g, ''); 
    console.log('Original: ' + s); 
    console.log('Result: ' + result); 
    } else { 
    console.log('No match: ' + s); 
    } 
}); 

Demo: JSBin

Edycja: updated pokrycie 3+ pojedynczych liter i przykład braku zgodności.

+0

Tak, zadziałało, ale nadal było stosowane do "R I" i "R I O", kiedy chciałbym, aby dotyczyło tylko 3 lub więcej pojedynczych liter. Wysłałem swoją odpowiedź, która robi coś podobnego do tego, ale działa z moim scenariuszem. Dzięki! – Flipybitz

+1

Zamiast kwantyfikatora '+ 'użyj' {3,} '. – Purag

+0

@Flipybitz można łatwo poprawić, używając '{3,}' zamiast '+'. –

0

Będziesz mieć problem rozwiązujący ten cały problem samymi wyrażeń regularnych.

To znaczy, nie ma wyrażenie regularne, że zrobi wszystko, co następuje:

  • wybierz nic nie jesteś zainteresowany
  • przechwytywania wszystko jesteś zainteresowany
  • wychwytywania zmienna liczba dopasowań

Ostatnie wymaganie - zmienna liczba przechwytów - jest duże. Użytkownik StackOverflow Tomalak described the situation quite well:

Grupy są zdefiniowane w nawiasach. Twój wynik meczu będzie zawierał tyle grup, ile par nawiasów w twoim regex (oprócz zmodyfikowanych nawiasów takich jak (?: ...), które nie będą się liczyć do grup dopasowania). Chcesz dwóch oddzielnych meczów grupowych w wyniku meczu? Zdefiniuj dwie oddzielne grupy w swoim regex.

Jeśli grupa może się równać wiele razy, wartością grupy będzie to, co pasowało do niej ostatnio. Wszystkie wcześniejsze wystąpienia meczów dla tej grupy zostaną zastąpione przez ostatnie dopasowanie.

Nadal można pozwolić wyrażenie regularne zrobić dużo prac, chociaż, na przykład za pomocą granica końca słowa kotwicę \b. Jest to bardzo podobne do tego, co opisujesz jako "przestrzeń przed i po", ale jest bliżej tego, co chcesz, ponieważ nie pasuje (lub nawet nie wymaga) samej przestrzeni.

> "R I O T".match(/\b\w\b/g) 
["R", "I", "O", "T"] 
> "FrankerZ R FrankerZ I FrankerZ O FrankerZ T".match(/\b\w\b/g) 
["R", "I", "O", "T"] 

Chciałeś ilościowe i oczywiście ten regex nie zawiera kwantyfikatorów:

> "test a b test".match(/\b\w\b/g) 
["a", "b"] 

Ale można to zrobić poza wyrażenia regularnego:

var individual_letters_re = /\b\w\b/g; 

function hiddenWord(sentence) { 
    letters = sentence.match(individual_letters_re); 
    if (letters && letters.length >= 3) { 
     return letters.join(""); 
    } 
    return ""; 
} 

> hiddenWord("R I O T") 
"RIOT" 
> hiddenWord("FrankerZ R FrankerZ I FrankerZ O FrankerZ T") 
"RIOT" 
> hiddenWord("test a b test") 
"" 
> hiddenWord("test a b c test") 
"abc" 
0

spróbować tego na terminalu/przeglądarka/konsola:

var text = "FrankerZ R I O T FrankerZ"; 
var new_text = text.replace(/(\s\S(?=\s)){3,}/g, function(w){ 
    return(' ' + w.replace(/\s/g, '')); 
}); 
console.log(new_text); 

Mam nadzieję, że spełni potrzeby.

Powiązane problemy