2014-12-15 12 views
6

Próbuję wykonać proste wyrażenie regularne. Zasadniczo chcę sprawdzić, czy w łańcuchu znaków są specjalne znaki, a jeśli tak, sprawdź każdy znak ciągu dla dwóch określonych znaków, np. Hipen i kropka.Błąd testu Regex - Java

Wydaje mi się, że mam problem w pierwszym kawałku, który polega na określeniu, czy mam specjalne znaki w ciągu znaków.

Poniżej jest moja metoda, którą staram się to następnie strun Mam problemy z zrobić:

public static boolean stringValidity(String input) { 
    int specials = 0; 

    Pattern p = Pattern.compile("[^a-zA-Z0-9 ]"); 
    Matcher m = p.matcher(input); 
    boolean b = m.find(); 

    if (b) { 
     System.out.println("\nstringValidity - There is a special character in my string"); 

     for (int i = 0; i < input.length(); ++i) { 

      char ch = input.charAt(i); 

      //if (!Character.isDigit(ch) && !Character.isLetter(ch) && !Character.isSpace(ch)) { 
       ++specials; 

       System.out.println("\nstringValidity - Latest number of special characters is: " + specials); 

       if((ch == '-') | (ch == '.')) { 
        specialCharValidity = true; 

        System.out.println("\nstringValidity - CHAR is valid - specialCharValidity is: " + specialCharValidity + " as char is: " + ch); 
       } else { 
        specialCharValidity = false; 

        System.out.println("\nstringValidity - CHAR is invalid - specialCharValidity is: " + specialCharValidity + " as char is: " + ch); 

        break; 
       } 
      //} 
     } 
    } else { 
     System.out.println("\nstringValidity - There is NO special character in my string"); 

     specialCharValidity = true; 
    } 

    return specialCharValidity; 
} 

poniżej są ciągi I przekazywane do metody, które spodziewałem się być traktowane jako ciągi ze specjalnym znaki ale test nie powiodła się:

"QWERTY"!£$"£$" 
"sdfGSDFGSDFG%*^(%*&(" 

Poniżej są ciągi I przekazywane do metody, która się spodziewałem nie powinna być traktowana jako ciągi znaków specjalnych, ale próba nie powiodła się:

"QWE12342134RTY" 
"LOREMIPSUM2354214" 

Wszelkie sugestie są mile widziane.

+0

Działa dla mnie ... 'Pattern.compile (" [^ a-zA-Z0-9] "). Matcher (" sdfGSDFGSDFG%^(% & ("). Find()' zwraca 'true '. ' Pattern.compile ("[^ a-zA-Z0-9]".) Matcher ("QWE12342134RTY"). Find() 'zwraca false – Dima

+0

Funkcja działa po odkomentowaniu skomentowanych linii. –

+0

@Dima and Salaman: Po odkomentowaniu instrukcji if i zmianie wzorca na [^ a-zA-Z0-9 \\ - \\.] Zadziałało. Dzięki za sugestie – TokTok123

Odpowiedz

0

Uruchamianie kodu z dostarczonych strun dała mi następujące wyjście:

stringValidity - There is a special character in my string 

stringValidity - Latest number of special characters is: 1 

stringValidity - CHAR is invalid - specialCharValidity is: false as char is: Q 
--- 

stringValidity - There is a special character in my string 

stringValidity - Latest number of special characters is: 1 

stringValidity - CHAR is invalid - specialCharValidity is: false as char is: s 
--- 

stringValidity - There is NO special character in my string 
--- 

stringValidity - There is NO special character in my string 
--- 

Myślę, że to oznacza, że ​​nie ma nic wro ng z wzorcem, którego używasz, aby znaleźć znaki specjalne (nie cyfry ani litery). Ale znalazłem następujące problemy z kodem:

  1. Upewnij się, że poprawnie przekazujesz te ciągi jako parametry. Pierwszy ciąg na twojej liście powinien zostać zadeklarowany w twoim programie jako "QWERTY \"! £ $ \ "£ $", gdy java wymaga podwójnych cudzysłowów w łańcuchach poprzedzonych zwrotnym ukośnikiem, aby nie były interpretowane jako ograniczniki ciągów;
  2. Druga część testu nie działa, ponieważ testowany jest tylko pierwszy znak w ciągu znaków. Twoja logika mówi coś w stylu: "jeśli obecny znak jest kropką lub łącznikiem, specialCharValidity = true, w przeciwnym razie (w przypadku, gdy jest to jakikolwiek inny nieprawidłowy LUB prawidłowy znak inny niż kropka i łącznik), po prostu ustaw wartość specialCharValidity = false i złam pętla". Dziwne, już zrobiłeś to, co trzeba: po prostu włącz ponownie wiersze, które skomentowałeś, aby wyświetlić prawidłowy nieprawidłowy znak. Jeśli chcesz włączyć odliczanie specials wystarczy usunąć linię z break, aby pętla nie zatrzymywała się w pierwszym specjalnym;

Kilka sugestii

  • Wymień Character.isSpace() z Character.isWhitespace() jako pierwsza wersja jest już przestarzała;
  • Lokalnie zdefiniuj specialCharValidity, aby uniknąć potencjalnych problemów;
  • Ze względu na wydajność, nie kompiluj tego samego wzorca przy każdym połączeniu, tak jak robisz na linii Pattern p = Pattern.compile("[^a-zA-Z0-9 ]");.Kompilacja wzoru jest czasochłonna, więc możesz po prostu zdefiniować stałą na górze klasy, np. static public final Pattern p = Pattern.compile("[^a-zA-Z0-9 ]"); i użyć jej później;
  • Wzory są doskonałym narzędziem do dopasowywania złożonych wzorów łańcuchów, ale w tym przypadku są nieco przesadzone. Jeśli potrzebujesz tylko dopasować/znaleźć takie znaki, lepiej pójdź sam na porównanie znaków, ponieważ wzorce po prostu dodadzą niepotrzebnego narzutu.
+0

Dziękuję za odpowiedź. koduj jeszcze raz, ale z [^ a-zA-Z0-9 \\ - \\.] jako wzorzec w przeciwieństwie do [^ a-zA-Z0-9]. Zasadniczo opierając się na odpowiedzi ulixa odkomentowując kontrole, które złożyłem, tj. isDigit(), isLetter() i isWhiteSpace() umożliwiają mi przetestowanie PAST 1. znaku. Testowałem to za pomocą t on struny, o których wspominałem w moim oryginalnym poście. Bardzo doceniam również Wasze dodatkowe sugestie, które zaimplementowałem i zleciłem mi oczyszczenie kodu. – TokTok123

1

Można uprościć kod zaznaczając ciąg przeciwko następującym wzorem:

[^a-zA-Z0-9 \-\.] 

Funkcja ważność ciąg sprowadza się do:

public static boolean stringValidity(String input) 
{ 
    return Pattern.compile("[^a-zA-Z0-9 \\-\\.]").matcher(input).find() == false; 
}