JavaRush /Blog Java /Random-PL /Metoda podziału w Javie: podziel ciąg znaków na części

Metoda podziału w Javie: podziel ciąg znaków na części

Opublikowano w grupie Random-PL
Porozmawiajmy o metodzie podziału ciągów : co robi i dlaczego jest potrzebna. Łatwo się domyślić, że dzieli sznurek, ale jak to działa w praktyce? Przyjrzyjmy się bliżej działaniu metody i omówmy kilka nieoczywistych szczegółów, a jednocześnie dowiedzmy się, ile tak naprawdę metod split znajduje się w klasie String . Chodźmy!

Definicja i podpis dla Java String.split

Metoda split w Javie dzieli ciąg na podciągi za pomocą ogranicznika określonego za pomocą wyrażenia regularnego. Podajmy sygnaturę metody i rozpocznijmy nurkowanie:
String[] split(String regex)
Z podpisu wynika jasno dwie rzeczy:
  1. Metoda zwraca tablicę ciągów.
  2. Metoda przyjmuje jako parametr ciąg znaków regex .
Przyjrzyjmy się każdej rzeczy osobno w świetle definicji podanej powyżej.
  1. Metoda zwraca tablicę ciągów.

    Definicja zawiera następujące słowa: „ Metoda split w Javie dzieli ciąg na podciągi”. Te podciągi są gromadzone przez metodę w tablicy i reprezentują wartość zwracaną.

  2. Metoda przyjmuje jako parametr ciąg znaków regex .

    Ponownie pamiętaj o definicji: „dzieli ciąg na podciągi za pomocą ogranicznika określonego za pomocą wyrażenia regularnego”. Akceptowany parametr regex to wzorzec wyrażenia regularnego stosowany do ciągu źródłowego i dopasowujący znak ogranicznika (lub kombinację znaków) w ciągu źródłowym.

Metoda podziału w Javie: podziel ciąg na części - 1

Podział w praktyce

Przejdźmy teraz do rzeczy. Wyobraźmy sobie, że mamy ciąg znaków ze słowami. Na przykład tak:
Kocham Javę
Musimy podzielić ciąg na słowa. Widzimy, że w tym wierszu słowa są oddzielone od siebie spacjami. Przestrzeń jest w tym przypadku idealnym kandydatem na rolę separatora. Tak wygląda kod rozwiązujący ten problem:
public class Main {
    public static void main(String[] args) {
        String str = "I love Java";
        String[] words = str.split(" ");
        for (String word : words) {
            System.out.println(word);
        }
    }
}
Wynikiem głównej metody będą następujące linie:
Kocham Javę
Przyjrzyjmy się jeszcze kilku przykładom działania metody split :
Linia Ogranicznik Wynik metody
„Kocham Javę” „ ” (znak spacji) { „Ja” , „kocham” , „Java” }
„192.168.0.1:8080” „:” { "192.168.0.1" , "8080" }
„Czerwony, pomarańczowy, żółty” „,” { "Czerwony" , "pomarańczowy" , "żółty" }
„Czerwony, pomarańczowy, żółty” „”, „ { "Czerwony" , "pomarańczowy" , "żółty" }
Zwróć uwagę na różnice pomiędzy dwoma ostatnimi wierszami powyższej tabeli. W przedostatnim wierszu ogranicznikiem jest przecinek, dlatego wiersz jest dzielony w taki sposób, że niektóre słowa mają spacje na początku. W ostatnim wierszu jako ogranicznika użyliśmy przecinka i spacji. Dlatego wynikowa tablica nie zawierała żadnych linii ze spacjami wiodącymi. To tylko mały szczegół, który pokazuje, jak ważny jest staranny dobór odpowiedniego separatora.

Wiodący ogranicznik

Jest jeszcze jeden ważny niuans. Jeśli ciąg źródłowy zaczyna się od ogranicznika, pierwszym elementem wynikowej tablicy będzie ciąg pusty. W przykładzie wyglądałoby to tak: Ciąg źródłowy: „Kocham Javę” Delimiter: „” Wynikowa tablica: { „” , „I” , „love” , „Java” } Ale jeśli ciąg źródłowy kończy się ogranicznikiem i nie zaczyna się, wynik będzie inny: Ciąg źródłowy: "Kocham Javę" Separator: " " Wynikowa tablica: { "I" , "love" , "Java" } Sprawdzamy w kodzie odmiany metody split ze znakiem separatora na końcu i/lub początku ciągu źródłowego:
public class Main {
    public static void main(String[] args) {
        print("I love Java".split(" "));
        print(" I love Java".split(" "));
        print("I love Java ".split(" "));
        print(" I love Java ".split(" "));
    }

    static void print(String[] arr) {
        System.out.println(Arrays.toString(arr));
    }
}
Wynik głównej metody będzie wyglądał następująco:
[Ja, miłość, Java] [, ja, miłość, Java] [Ja, miłość, Java] [, ja, miłość, Java]
Ponownie zauważ, że jeśli pierwszym znakiem w ciągu źródłowym jest znak ogranicznika, wynikowa tablica będzie miała pusty ciąg jako pierwszy element.

Przeciążony gość

Klasa String ma inną metodę podziału z tą sygnaturą:
String[] split(String regex, int limit)
Ta metoda ma dodatkowy parametr ograniczający : określa, ile razy wzorzec wyrażenia regularnego zostanie zastosowany do ciągu źródłowego. Poniżej znajdują się wyjaśnienia:

granica > 0

Stosowany jest limit -1 razy . W takim przypadku długość tablicy nie przekroczy wartości granicznej . Ostatnim elementem tablicy będzie część ciągu znajdująca się po ostatnim znalezionym ograniczniku. Przykład:
public class Main {
    public static void main(String[] args) {
        print("I love Java".split(" ", 1));
        print("I love Java".split(" ", 2));
        /*
         Dane wyjściowe:
         [Kocham Javę]
         [Kocham Javę]
        */
    }

    static void print(String[] arr) {
        System.out.println(Arrays.toString(arr));
    }
}

granica < 0

Wzorzec wyszukiwania ograniczników jest stosowany do ciągu tyle razy, ile to możliwe. Długość wynikowej tablicy może być dowolna. Przykład:
public class Main {
    public static void main(String[] args) {
        // Zwróć uwagę na spację na końcu linii
        print("I love Java ".split(" ", -1));
        print("I love Java ".split(" ", -2));
        print("I love Java ".split(" ", -12));
        /*
         Dane wyjściowe:
        [I, love, Java, ]
        [I, love, Java, ]
        [I, love, Java, ]

        Zauważ, że ostatni element tablicy jest
        pustym łańcuchem, wynikającym ze spacji
        na końcu oryginalny ciąg.
        */
    }

    static void print(String[] arr) {
        System.out.println(Arrays.toString(arr));
    }
}

granica 0

Podobnie jak w przypadku limit < 0, wzór ogranicznika jest stosowany do łańcucha tyle razy, ile to możliwe. Wynikowa tablica może mieć dowolną długość. Jeśli ostatnie elementy są równe pustemu ciągowi, zostaną odrzucone w końcowej tablicy. Przykład:
public class Main {
    public static void main(String[] args) {
        // Zwróć uwagę na spację na końcu linii
        print("I love Java ".split(" ", 0));
        print("I love Java ".split(" ", 0));
        print("I love Java ".split(" ", 0));
        /*
         Dane wyjściowe:
        [I, love, Java]
        [I, love, Java]
        [I, love, Java]
        Zwróć uwagę na brak pustych łańcuchów znaków na końcu tablic
        */
    }

    static void print(String[] arr) {
        System.out.println(Arrays.toString(arr));
    }
}
Jeśli przyjrzymy się implementacji metody split z jednym argumentem, zobaczymy, że metoda ta wywołuje swoje przeciążone rodzeństwo z drugim argumentem równym zero:
public String[] split(String regex) {
    return split(regex, 0);
}

Różne przykłady

W praktyce czasami zdarza się, że mamy linię skompilowaną według pewnych zasad. Ta linia może „wejść” do naszego programu z dowolnego miejsca:
  • z usługi strony trzeciej;
  • z żądania do naszego serwera;
  • z pliku konfiguracyjnego;
  • itp.
Zwykle w takiej sytuacji programista zna „reguły gry”. Załóżmy, że programista wie, że posiada informacje o użytkowniku, które są przechowywane według następującego wzorca:
id_użytkownika|login_użytkownika|e-mail_użytkownika
Weźmy na przykład określone wartości:
135|bender|bender@gmail.com
I teraz programista staje przed zadaniem napisania metody wysyłającej wiadomość e-mail do użytkownika. Do jego dyspozycji znajdują się informacje o użytkowniku zapisane w powyższym formacie. Cóż, podzadaniem, które będziemy nadal analizować, jest oddzielenie adresu e-mail od ogólnych informacji o użytkowniku. To jeden z przykładów, w którym metoda split może być użyteczna. Przecież jeśli spojrzymy na szablon, rozumiemy, że aby wyodrębnić adres e-mail użytkownika ze wszystkich informacji, wystarczy podzielić linię za pomocą metody split . Następnie adres e-mail znajdzie się w ostatnim elemencie wynikowej tablicy. Podajmy przykład takiej metody, która pobiera ciąg zawierający informacje o użytkowniku i zwraca adres e-mail użytkownika. Dla uproszczenia załóżmy, że ten ciąg zawsze odpowiada formatowi, którego potrzebujemy:
public class Main {
    public static void main(String[] args) {
        String userInfo = "135|bender|bender@gmail.com";
        System.out.println(getUserEmail(userInfo));
        // Dane wyjściowe: bender@gmail.com
    }

    static String getUserEmail(String userInfo) {
        String[] data = userInfo.split("\\|");
        return data[2]; // lub dane[długość danych - 1]
    }
}
Zwróć uwagę na separator: „\\|” . Ponieważ w wyrażeniach regularnych „|” - jest to znak specjalny, z którym wiąże się pewna logika; aby móc go używać jako zwykłego (tego, który chcemy znaleźć w ciągu źródłowym), musimy uciec przed tym znakiem za pomocą dwóch odwrotnych ukośników. Spójrzmy na inny przykład. Załóżmy, że mamy informacje o zamówieniu zapisane w przybliżeniu w następującym formacie:
numer_przedmiotu_1,nazwa_przedmiotu_1,cena_przedmiotu_1;numer_przedmiotu_2,nazwa_przedmiotu_2,cena_przedmiotu_2;...;numer_przedmiotu_n,nazwa_przedmiotu_n,cena_przedmiotu_n
Albo weźmy konkretne wartości:
1, ogórki 20,05, 2, pomidory 123,45, 3, zające 0,50
Stajemy przed zadaniem obliczenia całkowitego kosztu zamówienia. Tutaj będziemy musieli kilka razy zastosować metodę podziału . Pierwszym krokiem jest podzielenie ciągu znaków poprzez symbol „;” na części składowe. Wtedy w każdej takiej części będziemy mieli informację o konkretnym produkcie, który możemy w przyszłości przetworzyć. Następnie w ramach każdego produktu oddzielimy informacje symbolem „”, i z powstałej tablicy pobierzemy element z określonym indeksem (w którym przechowywana jest cena), przekonwertujemy go do postaci liczbowej i zestawiamy ostateczny koszt na rozkaz. Napiszmy metodę, która to wszystko obliczy:
public class Main {
    public static void main(String[] args) {
        String orderInfo = „1, ogórki, 20,05; 2, pomidory, 123,45; 3, zające, 0,50”;
        System.out.println(getTotalOrderAmount(orderInfo));
        // Dane wyjściowe: 144.0
    }

    static double getTotalOrderAmount(String orderInfo) {
        double totalAmount = 0d;
        final String[] items = orderInfo.split(";");

        for (String item : items) {
            final String[] itemInfo = item.split(",");
            totalAmount += Double.parseDouble(itemInfo[2]);
        }

        return totalAmount;
    }
}
Spróbuj sam przekonać się, jak działa ta metoda. Na podstawie tych przykładów można powiedzieć, że metodę split stosuje się wtedy, gdy mamy jakąś informację w formie stringu, z której musimy wydobyć trochę bardziej szczegółowe informacje.

Wyniki

Przyjrzeliśmy się metodzie split klasy String . Konieczne jest podzielenie ciągu znaków na części składowe za pomocą specjalnego ogranicznika. Metoda zwraca tablicę ciągów znaków (składników ciągu). Akceptuje wyrażenie regularne pasujące do znaków ogranicznika. Przyjrzeliśmy się różnym subtelnościom tej metody:
  • wiodący znak ogranicznika;
  • przeciążony brat dwoma argumentami.
Próbowaliśmy także symulować pewne sytuacje „z życia wzięte”, w których wykorzystaliśmy metodę podziału do rozwiązania wprawdzie fikcyjnych, ale całkiem realistycznych problemów.
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION