W java, jak uzyskać podciąg z ciągu do znaku c?


102

Mam ciąg znaków (który jest w zasadzie nazwą pliku zgodną z konwencją nazewnictwa) abc.def.ghi

Chciałbym wyodrębnić podciąg przed pierwszym .(tj. Kropką)

W java doc api nie mogę znaleźć metody w String, która to robi.
Czy coś mi brakuje? Jak to zrobić?

Odpowiedzi:


64

spójrz na String.indexOfi String.substring.

Upewnij się, że sprawdzasz -1 dla indexOf.


1
krótkie i słodkie. Pamiętaj również, że indexOf podaje pierwszy indeks podciągu.
Neil Chowdhury

112

Przyjęta odpowiedź jest poprawna, ale nie mówi, jak z niej korzystać. W ten sposób używasz razem funkcji indexOf i podciąg.

String filename = "abc.def.ghi";     // full file name
int iend = filename.indexOf("."); //this finds the first occurrence of "." 
//in string thus giving you the index of where it is in the string

// Now iend can be -1, if lets say the string had no "." at all in it i.e. no "." is found. 
//So check and account for it.

String subString;
if (iend != -1) 
{
    subString= filename.substring(0 , iend); //this will give abc
}

1
To jest nieprawidłowy kod, ponieważ nie można umieścić deklaracji zmiennej w treści instrukcji If bez nawiasów klamrowych.
Clashsoft

85

Możesz po prostu podzielić ciąg ...

public String[] split(String regex)

Zwróć uwagę, że java.lang.String.split używa wartości wyrażenia regularnego separatora. Zasadniczo w ten sposób ...

String filename = "abc.def.ghi";     // full file name
String[] parts = filename.split("\\."); // String array, each element is text between dots

String beforeFirstDot = parts[0];    // Text before the first dot

Oczywiście jest to podzielone na wiele linii dla jasności. Można to zapisać jako

String beforeFirstDot = filename.split("\\.")[0];

5
Twoja propozycja jest nieprawidłowa, ponieważ java.lang.String.split przyjmuje wartość wyrażenia regularnego jako atrybut, a nie tylko ciąg. Wszystko "." w Twoim przykładzie należy zmienić na „\\”. Wtedy to zadziała :)
Erik Kaju

2
Uwielbiam regex, ale za każdym razem mnie to łapie.
Chad Schouggins

71

Jeśli Twój projekt już używa commons-lang , StringUtils zapewnia przyjemną metodę do tego celu:

String filename = "abc.def.ghi";

String start = StringUtils.substringBefore(filename, "."); // returns "abc"

patrz javadoc [2.6] [3.1]


Czystsze niż inne rozwiązania.
userab

12

lub możesz spróbować czegoś takiego

"abc.def.ghi".substring(0,"abc.def.ghi".indexOf(c)-1);


3
nastąpi awaria „c” nie znajduje się w ciągu, ponieważ indexOf zwróci -1
TofuBeer

@Umer Hayat A co jeśli nazwa pliku to def.hij.klm? Jak wtedy działałby twój kod? (Twój kod działa tylko w tym jednym przykładzie - równie dobrze możesz napisać funkcję, która zwraca "abc"- działałaby równie dobrze)
Bohemian

@Bohemian: Wiem, że brakuje przypadków granicznych i kontroli. Była to konkretna odpowiedź na konkretne pytanie, a idea polegała na podaniu ogólnej idei na przykładzie :).
Umer Hayat

1
@TofuBeer: Ok, w porządku, jest zamieszanie, wcześniej „(tj. Kropka)” nie było w aktualnym poście. Myślę i mam nadzieję, że moja odpowiedź daje ogólny pomysł rozwiązania tego pokrewnego problemu.
Umer Hayat

2
Poszedłbym z: int ix = inString.indexOf ('.'); if (ix> -1) inString = inString.substring (0, ix); Nie wiem, dlaczego Umer zasugerował odejmowanie 1. Drugi argument podciągów i tak jest do, ale wyklucza.
Micha Berger,

4

A co powiesz na użycie wyrażenia regularnego?

String firstWord = filename.replaceAll("\\..*","")

Spowoduje to zastąpienie wszystkiego, od pierwszej kropki do końca, znakiem „” (czyli wyczyści go, pozostawiając Ci to, czego chcesz)

Oto test:

System.out.println("abc.def.hij".replaceAll("\\..*", "");

Wynik:

abc

7
Nie głosowałem przeciw (i zgadzam się, że to do niczego, kiedy ludzie głosują przeciw bez powodu), ale twoje rozwiązanie jest dość drogie i nie jest super oczywiste.
TofuBeer

1
@ Knickerless-Noggins Mogę to opisać, jeśli chcesz szczegółów, to też mogę zrobić ... ale nie wiem, jak mógłbym to zrobić w komentarzu (może będę musiał zrobić inne pytanie / odpowiedź). Jest drogi, ponieważ tworzy cały nowy ciąg wraz ze wszystkimi zastępującymi znakami. podciąg po prostu zwraca widok do ciągu. Ta pomoc?
TofuBeer

2
@TofuBeer nie masz racji. Ciągi znakówniezmienne . Podciąg nie zwraca widoku. Każdy ciąg zwrócony z metody String jest nowym ciągiem.
Bohemian

@ Knickerless-Noggins On się myli ... Zobacz ostatnie komentarze. Poza tym jest wystarczająco efektywny. Gęstość kodu jest wysoka - należałoby ją intensywnie wykorzystywać, aby uzasadnić dodawanie większej ilości kodu ze względu na „wydajność”.
Bohemian

Najwyraźniej zmieniło się to w JDK 7, javarevisited.blogspot.ca/2011/10/…
TofuBeer

2

W java.lang.String otrzymujesz metody, takie jak indexOf (): która zwraca pierwszy indeks znaku / ciągu znaków. i lstIndexOf: który zwraca ostatni indeks String / char

Z dokumentu Java:

  public int indexOf(int ch)
  public int indexOf(String str)

Zwraca indeks pierwszego wystąpienia określonego znaku w tym ciągu .


2

Oto kod, który zwraca podłańcuch od a Stringdo dowolnego z podanych znaków:

/**
 * Return a substring of the given original string until the first appearance
 * of any of the given characters.
 * <p>
 * e.g. Original "ab&cd-ef&gh"
 * 1. Separators {'&', '-'}
 * Result: "ab"
 * 2. Separators {'~', '-'}
 * Result: "ab&cd"
 * 3. Separators {'~', '='}
 * Result: "ab&cd-ef&gh"
 *
 * @param original   the original string
 * @param characters the separators until the substring to be considered
 * @return the substring or the original string of no separator exists
 */
public static String substringFirstOf(String original, List<Character> characters) {
    return characters.stream()
            .map(original::indexOf)
            .filter(min -> min > 0)
            .reduce(Integer::min)
            .map(position -> original.substring(0, position))
            .orElse(original);
}

1

To może pomóc:

public static String getCorporateID(String fileName) {

    String corporateId = null;

    try {
        corporateId = fileName.substring(0, fileName.indexOf("_"));
        // System.out.println(new Date() + ": " + "Corporate:
        // "+corporateId);
        return corporateId;
    } catch (Exception e) {
        corporateId = null;
        e.printStackTrace();
    }

    return corporateId;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.