2012-02-29 10 views
11

Mam pole wejściowe, które jest zlokalizowane. Muszę dodać sprawdzanie poprawności za pomocą wyrażenia regularnego, które musi zawierać tylko alfabety i liczby. Mogłem użyć [a-z0-9], jeśli używałem tylko angielskiego.Regex do sprawdzania poprawności alfabetycznej i liczb w zlokalizowanym ciągu

Do tej pory używam metody (tak, używam iteracji po każdym znaku), aby odfiltrować alfabety obecne w różnych językach.

Czy istnieją lepsze sposoby na zrobienie tego? Czy dostępne są do tego regex lub inne biblioteki?

+0

Więc chcesz obsługiwać również języki inne niż angielski, prawda? – Lukasz

+0

Szukam ogólnego rozwiązania ** w tym angielskiego ** – ManuPK

+1

Zgodnie z [to] (http://stackoverflow.com/questions/2392194/how-to-match-the-international-alphabet-english-az-non-english -with-a-regu) po "\ w" działa również w wyrażeniach regularnych perla na znaki Unicode, nie wiem, czy tak jest w regexach java. – user1227804

Odpowiedz

18

Ponieważ Java 7 można użyć Pattern.UNICODE_CHARACTER_CLASS

String s = "Müller"; 

Pattern p = Pattern.compile("^\\w+$", Pattern.UNICODE_CHARACTER_CLASS); 
Matcher m = p.matcher(s); 
if (m.find()) { 
    System.out.println(m.group()); 
} else { 
    System.out.println("not found"); 
} 

z obecnie opcja nie rozpozna słowo „Müller”, ale przy użyciu Pattern.UNICODE_CHARACTER_CLASS

Umożliwia wersji Unicode predefiniowanych klas postaci i Klasy znaków POSIX.

Zobacz here for more details

Można również spojrzeć here for more Unicode information w Javie 7.

a tu na regular-expression.info przegląd nad Unicode skrypty, właściwości i bloków.

See here a famous answer from tchrist o ograniczeniach z regex w Jawa oraz uaktualniony co się zmieniło z Java 7 (będzie w Java 8)

+0

Oczywiście będzie to również dopasować podkreślenia i inne łączące znaki interpunkcyjne. –

+0

@TimPietzcker ów prawdziwe, jeśli się liczy, to odpowiedź byłaby lepszym wyborem dla PO (+1 dla ciebie) – stema

+0

@TimPietzcker Under 'UNICODE_CHARACTER_CLASS', tak zwanych klas POSIX pasuje również za [UTS nr 18 załącznika C ] (http://unicode.org/reports/tr18/#Compatibility_Properties); oznacza to, że '\ p {alpha}' staje się - wtedy i tylko wtedy, gdy skompilowany pod flagą kompilacji 'Pattern' - dokładnie równy własności Unicode' Alphabetic = True', która sama jest nieco skomplikowana, ale całkiem użyteczna i która nie zawiera interpunkcji złącza. Przepraszam za zdane zdanie. :) – tchrist

8
boolean foundMatch = name.matches("[\\p{L}\\p{Nd}]*"); 

powinien działać.

dopasowuje znak będący literą lub cyfrą Unicode. Metoda regex .matches() zapewnia, że ​​cały ciąg pasuje do wzorca.

+1

Inne możliwe kategorie kodów Unicode (np. 'L' lub' N') można znaleźć [tutaj] (http://www.fileformat.info/info/unicode/category/index.htm). – beerbajay

+0

Nie potrzebujesz szelek dla 7 głównych kategorii. Możesz także polubić '\ pM', więc' [\ pL \ pM \ pN] '. Zauważ, że jest to już szersza definicja niż '\ p {Alfabetycznie}', ponieważ zawiera wszystkie znaki, a nie tylko niektóre z nich. To przybliża ją do właściwości '\ p {word}' używanej dla identyfikatorów programów, która na [UTS # 18 Annec C] (http://unicode.org/reports/tr18/#Compatibility_Properties) to '[\ p { alpha} \ p {gc = Mark} \ p {gc = Digit} \ p {gc = Pc}] ', gdzie' \ p {alpha} 'jest skomplikowane, ale w zasadzie wybiera tylko kilka znaków. – tchrist

+0

@TimPietzcker Hold on: Twój test boolowski jest nieprawidłowy. Wszystkie możliwe ciągi odpowiadają zero lub więcej powtórzeń czegokolwiek. Nie sądzę, że chcesz tę gwiazdę. Ponadto, jak skomentowano gdzie indziej, chociaż prawdopodobnie tego chcesz, '\ pN' jest czymś więcej niż cyframi; '\ p {Nd}' jest po prostu cyframi dziesiętnymi bez cyfr rzymskich, wulgarnych frakcji, pod-i górnego indeksu itd. Po prostu wywołaj '\ pN' dowolną cyfrę, a nie dowolną cyfrę, i będziesz miał rację. – tchrist

1

Niektórzy ludzie, w konfrontacji z problemem, pomyśl: „Wiem, Użyję wyrażeń regularnych . " Teraz mają dwa problemy.

- Jamie Zawinksi

mówię to żartem, ale iteracja String jak robisz będzie mieć wydajność wykonania przynajmniej tak dobry, jak każdy regex - Nie ma mowy, regex może robić to, co chcesz szybciej; i nie masz na głowie kompilacji wzoru.

Tak długo, jak:

  • walidacja nie trzeba robić nic innego regex-like (nic nie zostało wymienione w pytaniu)
  • intencją kodu pętli poprzez łańcuch jest jasne (jeśli nie, refactor, dopóki nie jest)

dlaczego następnie zastąpić go regex tylko dlatego, że można?

+2

Byłoby interesujące kopii zapasowej tego roszczenia przez pomiary. –

+0

+1 możesz się zgodzić lub się z nim nie zgodzić, to naprawdę ciekawy link! – ManuPK

+0

@Tim: naprawdę nie potrzebujesz pomiarów. Jeśli nie używasz komputerowych obliczeń kwantowych, nie możesz zweryfikować, czy wszystkie znaki na liście znaków (zwane też Ciągiem) są literami lub cyframi bez odwiedzania każdej postaci i zatrzymują się, gdy tylko znajdziesz inną, która nie jest. Ponieważ to właśnie robi niestandardowy kod, jest to minimalna możliwa ilość pracy. Regeksy nie są magiczne. –

Powiązane problemy