У Java як отримати підрядку від рядка до символу c?


101

У мене є рядок (в основному це ім'я файлу, що відповідає умові іменування) abc.def.ghi

Я хотів би витягнути підрядку до першої .(тобто крапки)

У java doc api я не можу знайти метод String, який це робить.
Я щось пропускаю? Як це зробити?

Відповіді:


65

дивитись на String.indexOfі String.substring.

Переконайтеся, що ви перевірили -1 indexOf.


1
короткий і милий. Також пам’ятайте, що indexOf дає перший індекс підрядка.
Ніл Чоуддурі

112

Прийнята відповідь правильна, але вона не говорить вам, як її використовувати. Таким чином ви разом використовуєте функції indexOf та substring.

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
Це недійсний код, оскільки ви не можете поставити змінну декларацію в тілі If-заяви без дужок.
Clashsoft

84

Ви можете просто розділити рядок ..

public String[] split(String regex)

Зауважте, що java.lang.String.split використовує значення регулярного вираження роздільника. В основному так ...

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

Звичайно, це розбито на кілька рядків для наочності. Це можна було б записати як

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

5
Ваша пропозиція неправильна, тому що java.lang.String.split приймає значення атрибута, а не лише рядок. Усі "." у вашому прикладі потрібно змінити на "\\." Тоді це спрацює :)
Ерік Каджу

2
Я люблю регулярний вираз, але це отримує мене щоразу.
Чад Шуггінс

70

Якщо у вашому проекті вже використовується commons-lang , StringUtils надає приємний метод для цієї мети:

String filename = "abc.def.ghi";

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

див. javadoc [2.6] [3.1]


Чистіше, ніж інші рішення.
userab

12

або ви можете спробувати щось подібне

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


3
крах 'c' не буде в рядку, оскільки indexOf повернеться -1
TofuBeer

@Umer Hayat Що робити, якщо ім'я файлу def.hij.klm? Як би тоді працював ваш код? (Ваш код працює лише для цього прикладу - ви також можете написати функцію, яка повертається "abc"- вона буде працювати так само добре)
Bohemian

@Bohemian: Я знаю, що відсутні граничні випадки та чеки відсутні. Це була конкретна відповідь на конкретне питання, а ідея полягала в тому, щоб дати загальне уявлення на прикладі :).
Умер Хаят

1
@TofuBeer: Добре, раніше є плутанина раніше (тобто крапка) "не було там у фактичному пості. Я думаю і сподіваюсь, що моя відповідь дає загальну ідею для вирішення цієї проблеми.
Умер Хаят

2
Я б пішов з: int ix = inString.indexOf ('.'); якщо (ix> -1) inString = inString.substring (0, ix); Я не знаю, чому Умер запропонував відняти 1. Другий аргумент підрядка дорівнює, але все одно виключає.
Micha Berger

4

Як щодо використання регулярного вираження?

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

Це замінює все від першої точки до кінця на "" (тобто очищає його, залишаючи вам те, що ви хочете)

Ось тест:

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

Вихід:

abc

7
Я не брав участь у програмі (і я погоджуюся, що це відстійно, коли люди звертаються з безвідмовної причини), але ваше рішення досить дороге і не надто очевидно.
TofuBeer

1
@ Knickerless-Noggins Я можу описати це, якщо ви хочете конкретики, я можу це зробити і ... але не впевнений, як я міг би це зробити в коментарі (можливо, доведеться зробити ще одне питання / відповідь). Це дорого, оскільки створює цілу нову рядок разом із усіма замінюючими символами. підрядка просто повертає вигляд у рядок. Що допомогти?
TofuBeer

2
@TofuBeer ви неправі. Струни незмінні . Підрядка не повертає перегляд. Кожна струна, повернута методом String, є новою .
богем

@ Knickerless-Noggins Він помиляється ... Дивіться останні коментарі. Крім того, це досить ефективно. Щільність коду висока - його потрібно було б інтенсивно використовувати для виправдання додавання ще коду заради «продуктивності».
богем

Це, мабуть, змінилося в JDK 7, javarevisited.blogspot.ca/2011/10/…
TofuBeer

2

У java.lang.String ви отримуєте такі методи, як indexOf (): який повертає вам перший індекс char / string. та lstIndexOf: який повертає вам останній індекс String / char

Від Java Doc:

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

Повертає індекс всередині цього рядка першого появи вказаного символу.


2

Ось код, який повертає підрядку від Stringдо будь-якого із заданого списку символів:

/**
 * 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

Це може допомогти:

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.