Java - второе последнее вхождение символа в строку

Предположим, у меня есть строка

String path = "the/quick/brown/fox/jumped/over/the/lazy/dog/";

Я хотел бы получить следующий результат

String output = "the/quick/brown/fox/jumped/over/the/lazy/";

Я думал, что подойдет следующее

output = path.substring(0, path.lastIndexOf("/", 1));

учитывая, как говорит документ

Returns the index of the first (last) occurrence of the specified character, searching forward (backward) from the specified index.

но это, похоже, не работает.

Любая помощь будет оценена.

Что именно не работает? Нам нужна дополнительная информация.

DWuest 11.01.2019 07:59

Вроде сканирует с начала, а не с конца. Так что на выходе получается просто /.

antikbd 11.01.2019 08:01

Как указано в документах. Метод возвращает только значение индекса, а не строку

hatati 11.01.2019 08:02

^ Это была опечатка

antikbd 11.01.2019 08:04

Помните, что с substring(start , end) делает подстроку из start в, но не включая 'индекс end. Поэтому, если вам нужен последний / в выходной строке, просто добавьте +1 к вашему end.

hatati 11.01.2019 08:08
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
5
13 319
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Второй параметр метода lastIndexOf указывает максимальный индекс, до которого метод должен искать строку. Это значит, что в вашем случае

path.lastIndexOf("/", 1)

возвращает первый индекс "/", индекс которого меньше 1.

Ага, теперь проблема. Спасибо за помощь.

antikbd 11.01.2019 08:28

Прежде всего, lastIndexOf вернет индекс, а не строку. Он также ищет назад из указанного индекса 1, поэтому он будет смотреть только на все до, включая символ с индексом 1. Это означает, что он проверяет только t и h. Как и ожидалось, ничего не находит и возвращает -1.

Вам следует просто опустить второй аргумент, если вы хотите искать по всей строке.

Кроме того, для достижения желаемой выходной строки (я полагаю, вы хотите удалить последний компонент пути?), Вы можете использовать replaceAll с регулярным выражением:

String output = path.replaceAll("[^/]+/$", "");

Спасибо за объяснение. Я думаю, вы правы - регулярное выражение - лучший способ справиться с этим. Кстати, я не голосовал против тебя.

antikbd 11.01.2019 08:27

Использование Apache Commons IO

String output = org.apache.commons.io.FilenameUtils.getPath(path);

Не использую Apache

public static String removeLastPart(String str) {
    int pos = str.length() - 1;

    while (str.charAt(pos) != '/' || pos + 1 == str.length()) {
        pos--;
    }

    return str.substring(0, pos + 1);
}
Ответ принят как подходящий

Это работает, учитывая длину path> 2

final String path = "the/quick/brown/fox/jumped/over/the/lazy/dog/";
final int secondLast = path.length()-2;
final String output = path.substring(0, path.lastIndexOf("/",secondLast)+1);
System.out.println(output);

Кажется, что каждый ответ предполагает, что вы уже знаете входную строку и точное положение последнего вхождения "/" в ней, хотя обычно это не так ...
Вот еще одно вхождение символа внутри строки общий метод получения n-го-последнего (второе-последнее, третье-последнее и т. д.):

static int nthLastIndexOf(int nth, String ch, String string) {
    if (nth <= 0) return string.length();
    return nthLastIndexOf(--nth, ch, string.substring(0, string.lastIndexOf(ch)));
}

Использование:

    String s = "the/quick/brown/fox/jumped/over/the/lazy/dog/";
    System.out.println(s.substring(0, nthLastIndexOf(2, "/", s)+1)); // substring up to 2nd last included
    System.out.println(s.substring(0, nthLastIndexOf(3, "/", s)+1)); // up to 3rd last inc.
    System.out.println(s.substring(0, nthLastIndexOf(7, "/", s)+1)); // 7th last inc.
    System.out.println(s.substring(0, nthLastIndexOf(2, "/", s))); // 2nd last, char itself excluded

Вывод:

the/quick/brown/fox/jumped/over/the/lazy/
the/quick/brown/fox/jumped/over/the/
the/quick/brown/
the/quick/brown/fox/jumped/over/the/lazy

Однозначно буду спасать это. Очень гибкий.

antikbd 11.01.2019 16:19

Если вы имеете дело с путями и файлами, почему бы не использовать встроенные классы? Что-то вроде ниже мне кажется проще, чем манипуляции со строками:

Path path = Paths.get("the/quick/brown/fox/jumped/over/the/lazy/dog/");
System.out.println(path.getParent());
// prints: the\quick\brown\fox\jumped\over\the\lazy
System.out.println(path.getParent().getParent());
// prints: the\quick\brown\fox\jumped\over\the

Например, Строковый ключ = "aaa / bbb / ccc / ddd";

и мне нужна моя строка результата как «ccc / ddd». то есть подстрока второго последнего индекса "/". Помогает следующий код:

    String key = "aaa/bbb/ccc/ddd";
    key=key.substring(key.substring(0, key.lastIndexOf("/")).lastIndexOf("/")+1);

Окончательное значение ключа будет «ccc / ddd».

Вот пример использования:

        String url = "http://localhost:4000/app/getPTVars";
        int secondLastIndexOf = url.substring(0, url.lastIndexOf('/')).lastIndexOf('/');
        System.out.println(secondLastIndexOf);
        System.out.println(url.substring(secondLastIndexOf, url.length()));

и вывод:

21
/app/getPTVars

Попробуйте подход - 1:

int j = path.lastIndexOf("/");
int i = path.lastIndexOf("/", j - 1);      // the 2nd last index from the last index

String output = path.substring(0, i + 1);  // inclusive

Другие вопросы по теме