2012-11-29 15 views
7

Piszę aplikację, która pozwala użytkownikowi określić wyrażenie regularne. Oczywiście użytkownicy popełniają błędy, więc potrzebuję sposobu na obsługę wyrażeń regularnych, które są nieosiągalne, i udzielę użytkownikowi porady, jak rozwiązać problem.Rozumienie wyrażeń regularnych analizowanie wyjątków w JavaScript

Problem polega na tym, że wyjątki generowane przez new RegExp("something awful") nie są przydatne dla regex n00bs i mają różne komunikaty na przeglądarkę. Na przykład:

Dane:

try{ 
    new RegExp("(pie"); 
}catch(e){ 
    console.log(e.message); 
} 
  • Firefox wyrzuca "niezakończony nawias".
  • Safari rzuca „missing)”
  • Chrome rzuca „grupę niezakończony”

I nie zdziwiłbym się, gdyby te struny są wiadomości użytkownika języka zlokalizowane, lub że już oddaliła się w czasie , dzięki czemu jest to zwariowany węzeł, który można rozwiązać za pomocą wyjątku.message.

Moim celem jest uchwycić wyjątek, dowiedzieć się, o co naprawdę chodzi, i umieścić o wiele bardziej przyjazny dla początkujących komunikat. (I ostatecznie podświetlając niedopasowany paren, w tym przykładzie.)

Czy jest jakiś inny identyfikator wyjątku, którego powinienem używać? Czy istnieje lepszy sposób na odróżnienie tych elementów od siebie? Po tym wszystkim, czy ktoś po prostu zebrał wszystkie te ciągi w kilku najpopularniejszych przeglądarkach?

+1

Chciałbym sprawdzić, co niektóre popularne strony testowania online regex zrobił – mplungjan

+1

Czy regex '(abcd})' mają jedno za mało nawiasów klamrowych lub jeden za dużo? –

+0

A oto sztuczka, aby zdobyć większość możliwych wiadomości. Napisz skrypt zawierający kilka poprawnych, ale bardzo skomplikowanych wyrażeń regularnych. Naprawdę używam i nadużywam wszystkich funkcji regex dostępnych w JavaScript. I gniazdowania ich i wszystkiego oczywiście. Następnie losowo usuń, dodaj lub zmień kilka znaków w tych i spróbuj je skompilować. I zapisz wszystkie komunikaty o błędach, które otrzymasz (wraz z regex, który je spowodował). Ze względu na losowość powinieneś być w stanie wypróbować wiele nieudanych przypadków, a dzięki automatyzacji nie musisz się martwić duplikatami. –

Odpowiedz

3

Pomysł: Zorientuj wszystko w czasie wykonywania. Na przykład.

var tellMeWhatIDidWrong = (function() { 

    var tests = { 
     '(': 'You did not close your group... duh!', 
     ')': 'You seem to have an unmatched parenthesis.', 
     '*': 'That token is illegal in that position' 
    }; 

    var errors = {}; 

    for (var i in tests) { 
     try { RegExp(i); } catch(e) { 
      errors[String(e).split(':').pop()] = tests[i]; 
     } 
    } 


    return function(regexStr) { 
     try { RegExp(regexStr); } catch(e) { 
      e = String(e).split(':').pop(); 
      if (e in errors) { 
       return errors[e]; 
      } 
      return 'Unknown error'; 
     } 
     return 'Nothing -- it is fine!'; 
    }; 

}()); 

tellMeWhatIDidWrong('(abc?'); // -> "You did not close your group... duh!" 

Oczywiście będzie to działało dobrze tylko wtedy, gdy wbudowana w przeglądarce wbudowana funkcja zgłaszania błędów jest wystarczająco specyficzna. Wielu z nich jest do bani. Na przykład. Opera nie daje absolutnie żadnej wskazówki co do tego problemu, więc powyższe nie będzie działało dobrze i żadne inne rozwiązanie nie będzie zależało od natywnych komunikatów o błędach Opery.

Proponuję wysyłanie wyrażeń regularnych off do aplikacji uruchomiony node.js i coraz ładne komunikaty o błędach V8 :)

+0

To jest naprawdę sprytne i dziękuję za zaglądnięcie do Opery (której nie było na mojej liście, aby spróbować). Aplikacja ma już komponent Node.js po stronie serwera, i masz rację, może być sensownym oczekiwaniem na podróż w obie strony i otrzymaniem doskonałej porady od serwera zamiast przeciętnej porady od klienta. –

1

obserwuję z mojego komentarza, I hacked razem trochę skrypt do możliwych komunikatów o błędach „żniwa” i wzorców, które je wywołują.

JSFiddle (próbowałem na Chrome tylko, Mam nadzieję obiekty wyjątków RegExp mają taką samą strukturę dla innych przeglądarek)

Pomysł jest taki: Masz pracę wyrażenie regularne, który używa tyle regex funkcje, jak to możliwe . Następnie losowo mutuj (dodawaj, usuwaj lub zamieniaj znaki) i próbuj je skompilować. Możesz to zrobić kilka tysięcy razy i zebrać wszystkie komunikaty o błędach. Mam nadzieję, że szansa jest lepsza w wymyślaniu możliwych możliwych zniekształconych wzorów niż ktokolwiek z nas.

Należy zdecydowanie poprawić wzór bazową, w celu włączenia wszystkie regex funkcji oferowanych przez JavaScript i obejmują wszystkie znaków meta w tabeli zastępczej. Ale poza tym, wydaje mi się, aby konsekwentnie uzyskać 6 ewentualne komunikaty o błędach:

Unterminated group 
Invalid group  
Nothing to repeat 
Unmatched ')' 
Unterminated character class 
\ at end of pattern 

Spróbuj uruchomić ten skrypt w innej przeglądarce, analizy wzorców, które spowodowały błędy, a stamtąd powinny być w stanie napisać swoje narzędzia.

EDIT:

Dobra, jak się obawiałem to nie działa w innych przeglądarkach po wyjęciu z pudełka, ponieważ przechowywać rzeczywiste wiadomość gdzieś wewnątrz obiektu wyjątku. Ale sądząc po twoim pytaniu, już wiesz, skąd wziąć wiadomość dla każdej przeglądarki, więc zmiany, które musisz wprowadzić, powinny być niewielkie, mam nadzieję.

Powiązane problemy