Negacja w wyrażeniach regularnych

0

Chcę przejrzeć Stringi pod kątem ich zawartości. Mogą tylko zawierać litery (małe i duże) i nic więcej.
Nie mam problemu z umieszczeniem w kodzie sprawdzania wyrażeń regularnych, tylko z budową samego wyrażenia.

Np:
[A-z]+
Sprawdzi czy mam podane jedną lub więcej liter - no i ok. A jak odrzucić całą resztę? Jak np można negować coś takiego:
[0-9]
??

0

Rzutuj tego Stringa do tablicy char, a następnie porównaj każdy jej element z interesującymi Cię wartościami liczbowymi tablicy ASCII. Typ char nie przechowuje tak naprawdę znaków, lecz liczby. Wykonaj więc porównanie w rodzaju

char[] tab = {'1', '2', 'c', 'B'};
if(tab[0] > 90 && tab[0] < 65)
{
    // znak inny niż duża litera, wycinam.
}

http://pl.wikipedia.org/wiki/ASCII

Możesz zrobić to inaczej. Wycinając ze stringów każdy znak z osobna metodą substring(), rzutuj go na char i porównuj z interesującymi Cię zakresami.

0

Negacja: [^0-9]

Tak ogolnie to [A-z] nie obsluguje np. polskich znakow z ogonkami itp, uzyj \w albo jakiejs klasy (poczytaj API).
Pomysl z wycinaniem substringa i porownywanie do ASCII, pomijajac ze jest bez sensu i niesamowicie niewydajny (juz lepiej petla po string.toCharArray() latac) rowniez posiada ten sam problem.

0
twojString.matches("[a-zA-Z]+")

Jeśli pasuje do wzorca, to jednocześnie nie może zawierać innych znaków (bo nie ma ich w regeksie).
A co do liter Unicode, to masz:

twojString.matches("\\pL+")
0
mućka napisał(a)

Pomysl z wycinaniem substringa i porownywanie do ASCII, pomijajac ze jest bez sensu i niesamowicie niewydajny (juz lepiej petla po string.toCharArray() latac) rowniez posiada ten sam problem.

Mój sposób, ma złożoność obliczeniową dążącą do liniowej. Biorąc więc pod uwagę fakt że jest uniwersalny, oraz możliwości współczesnych komputerów ... moim zdaniem wyczerpuje zagadnienie. To jaką zastosować pętlę, lub gdzie postawić if'a jest rzeczą wtórną.

Obsługiwane są zarówno polskie znaki jak i wszystkie inne.
Tutaj extended ASCII:
http://www.ascii-code.com/
zaś tutaj kody polskich znaków(dla webmasterów, ale kody ascii dla javy są takie same):
http://webdesign.about.com/od/localization/l/blhtmlcodes-pl.htm

public class JavaApplication451 {

    public static void main(String[] args) 
    {

        char znak = 261;

        if(znak == 'ą')
            System.out.println("true");
        else
            System.out.println("false");
    }
} 
0

Nie jest uniwersalne. Rozwiązanie z regexem mieści się w linijce kodu. Metoda z substringiem nie dość, że wymaga iterowania po całym ciągu, to jeszcze tworzy tyle nowych Stringów, ile masz znaków. Można by zrobić to normalnie, po znaku, ale ten sposób wciąż nie będzie poprawny dla wszystkich przypadków:

public static boolean containsOnlyLetters1(String string) {
    return string.matches("\\pL*");
}

public static boolean containsOnlyLetters2(String string) {
    for (int i = 0; i < string.length(); i++) {
        if (!Character.isLetter(string.charAt(i))) {
            return false;
        }
    }
    return true;
}

public static void main(String[] args) {
    String string = "\uD800\uDC00";  // LINEAR B SYLLABLE B008 A (U+10000)
    System.out.println(containsOnlyLetters1(string));  // true
    System.out.println(containsOnlyLetters2(string));  // false
}

Tak więc nie jest ani uniwersalne, ani nie obsługuje wszystkich znaków. Dopiero takie rozwiązanie będzie poprawne:

public static boolean containsOnlyLetters3(String string) {
    int i = 0;
    while (i < string.length()) {
        int codePoint = Character.codePointAt(string, i);
        if (!Character.isLetter(codePoint)) {
            return false;
        }
        i += Character.charCount(codePoint);
    }
    return true;
}
0

Hmm, dzięki. Nauczyłem się czegoś nowego.

0

A wynika to z tego, że niektóre znaki w Unicode kodowane są na dwóch charach (supplementary code points).

0
Noran napisał(a)

Mój sposób, ma złożoność obliczeniową dążącą do liniowej. Biorąc więc pod uwagę fakt że jest uniwersalny, oraz możliwości współczesnych komputerów ... moim zdaniem wyczerpuje zagadnienie. To jaką zastosować pętlę, lub gdzie postawić if'a jest rzeczą wtórną.

Obsługiwane są zarówno polskie znaki jak i wszystkie inne.

Bzdura, ale nie chce mi sie nawet zaglebiac w szczegoly. Jak za pomoca kodow ascii chcesz obsluzyc wszystkie znaki Unicode, np takie ktore maja 2, 3, 4, 5 lub nawet 6 bajtow jest dla mnie zagadka. To ze 261 jest ą w cp1250 czy czymkolwiem nic nie znaczy. Poczytaj jeszcze.

Nikt nie mowi ze rozwiazanie z regexem jest super szybkie, faktem jest jednak ze nie tworzysz setek obiektow wiec np GC sie na pewno nie wlacyz i nie zatrzyma swiata. Za to jest czytelne (jak ktos zna regexy). Poczytaj jeszcze.

0

Chwilka, momencik. Być może źle się wyraziłem, lub ktoś mnie źle zrozumiał. Pytanie było o litery, prawda? Odpowiedź dotyczyła więc liter, a następnie liter z polskimi znakami. Proponuję również podchodzić do tego mniej ambicjonalnie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0