Есть ли эквивалент Java для Python Easy String Splicing?

Хорошо, я хочу знать, есть ли способ с Java сделать то, что Python может сделать ниже...

string_sample = "hello world"

string_sample[:-1]
>>> "hello world"

string_sample[-1]
>>> "d"

string_sample[3]
>>> "l"

Поскольку мне кажется, что Java заставляет вас работать для одного и того же результата (мне особенно нравится каждый раз использовать 2 числа и отсутствие -1 для обозначения последнего символа)

String string_sample = "hello world";

string_sample.substring(0,string_sample.length()-1);
>>> "hello world"

string_sample.substringstring_sample.length()];
>>> "d"

string_sample.(3,4);
>>> "l"

Я еще не перешел к массивам/спискам на Java, поэтому я надеюсь, что у Java есть что-то более легкое, чем это

Изменить: Поправлено 'i' в 'l' для string_sample [3]. Хорошо заметили Марун!

Ответы

Ответ 1

Извините, Java substring не такой гибкий, как нотация фрагмента Python.

В частности:

  • Вы можете дать ему только начало, или начало и конец, но не просто конец. (Кроме того, нет шагов, но вы не пропустите это.)
  • Отрицательные индексы - это ошибка, а не счет с конца.

Здесь вы можете увидеть документы .

Однако, это не сложно написать это самостоятельно:

public String slice_start(String s, int startIndex) {
    if (startIndex < 0) startIndex = s.length() + startIndex;
    return s.substring(startIndex);
}

public String slice_end(String s, int endIndex) {
    if (endIndex < 0) endIndex = s.length() + endIndex;
    return s.substring(0, endIndex);
}

public String slice_range(String s, int startIndex, int endIndex) {
    if (startIndex < 0) startIndex = s.length() + startIndex;
    if (endIndex < 0) endIndex = s.length() + endIndex;
    return s.substring(startIndex, endIndex);
}

Поместите их как статические методы некоторого класса утилиты.

Очевидно, что это не совсем то же самое, что и Python, но он, вероятно, обрабатывает все случаи, которые вам нужны, и очень прост. Если вы хотите обрабатывать другие граничные случаи (включая такие вещи, как шаг и прохождение срезов и т.д.), Вы можете добавить любой дополнительный код, который вы хотите; ничто из этого не является особенно сложным.


Другие последовательности в основном одинаковы, но там вам нужно subSequence вместо substring. (Вы можете также использовать subSequence для строк, потому что String - CharSequence.)

Массивы на самом деле не являются типом последовательности; вам нужно написать код, который явно создает новый массив и копирует подматрицу. Но это все еще не намного сложнее.


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

Ответ 2

Java Boon Slice Notation позволяет все это и со строками, списками, наборами, картами и т.д.

Во многих языках есть нотация фрагментов (Ruby, Groovy и Python). Boon добавляет это в Java.

Boon имеет три оператора slc: slc, slc (только начало) и slcEnd.

С помощью Boon вы можете срезать строки, массивы (примитивные и общие), списки, наборы, наборы деревьев, карту деревьев и многое другое.

Обозначения фрагментов - нежное введение

Операторы среза boon работают как нотация фрагмента Python/Ruby:

Обозначение нотации Ruby

 arr = [1, 2, 3, 4, 5, 6]
 arr[2]    #=> 3
 arr[-3]   #=> 4
 arr[2, 3] #=> [3, 4, 5]
 arr[1..4] #=> [2, 3, 4, 5]

Обозначение фрагмента Python

string = "foo bar" 
string [0:3]  #'foo'
string [-3:7] #'bar'

Далее следует отличная запись в нотации фрагмента Python:

Основы нот среза следующие:

Обозначение фрагмента Python

     a[ index ]       # index of item
     a[ start : end ] # items start through end-1
     a[ start : ]     # items start through the rest of the array
     a[ : end ]       # items from the beginning through end-1
     a[ : ]           # a copy of the whole array

Обозначение фрагмента Java с помощью Boon:

      idx( index )         // index of item
      slc( a, start, end ) // items start through end-1
      slc( a, start )      // items start through the rest of the array
      slcEnd( a, end )     // items from the beginning through end-1
      copy( a )            // a copy of the whole array

slc означает фрагмент idx обозначает индекс slcEnd обозначает конечный срез. копия означает "хорошо", "ошибка", "копия", конечно,

Ключевым моментом, который следует помнить, является то, что конечное значение представляет первое значение, которое не находится в выбранном фрагменте. Таким образом, разница между окончанием и началом - это количество выбранных элементов. Другая особенность заключается в том, что начало или конец может быть отрицательным числом, что означает, что он отсчитывается от конца массива, а не от начала.

Таким образом:

Обозначение фрагмента Python с отрицательным индексом

         a[ -1 ]    # last item in the array
         a[ -2: ]   # last two items in the array
         a[ :-2 ]   # everything except the last two items

отрицательный индекс Java

         idx   ( a, -1)     // last item in the array
         slc   ( -2 )       // last two items in the array
         slcEnd( -2 )       // everything except the last two items

Python и Boon являются добрыми к программисту, если количество элементов меньше, чем вы просите: Python не позволяет вам выйти за пределы, если вы это сделаете, это приведет к худшему списку. Бун следует этой традиции, но предоставляет возможность получить исключение за пределы (описано ниже). В Python и Boon, если вы заходите далеко, вы получаете длину, если вы пытаетесь перейти под 0, вы получаете 0 (ниже 0 после расчета). И наоборот, Ruby дает вам нулевой указатель (Nil). Boon копирует стиль Python как одну из целей Boon, чтобы избежать когда-либо возвращаемого значения null (вы получаете исключение, вариант). (У Boon есть второй оператор с именем zlc, который выдает исключение индекса за пределами границ, но большинство людей должно использовать slc.)

Например, если вы запрашиваете slcEnd (a, -2) (a [: - 2]) и только один элемент, вы получаете пустой список вместо ошибки. Иногда вы предпочитаете ошибку, и с Boon у вас есть эта опция.

Больше нарезки

Вот некоторые основные типы Java, список, массив, veggies, примитивный массив char и примитивный байтовый массив.

Объявить переменные для работы с Boon

//Boon works with lists, arrays, sets, maps, sorted maps, etc.
List<String> fruitList;
String [] fruitArray;
Set<String> veggiesSet;
char [] letters;
byte [] bytes;
NavigableMap <Integer, String> favoritesMap;
Map<String, Integer> map;

//In Java a TreeMap is a SortedMap and a NavigableMap by the way.

Boon поставляется с вспомогательными методами, которые позволяют вам легко создавать списки, наборы, карты, параллельные карты, сортированные карты, отсортированные наборы и т.д. Вспомогательные методы являются safeList, list, set, sortedSet, safeSet, safeSortedSet и т.д. Идея состоит в том, чтобы сделать Java более похожим на список, а карты построены в типах.

Инициализировать набор, список, массив строк, массив символов и массив байтов

veggiesSet  =  set( "salad", "broccoli", "spinach");
fruitList   =  list( "apple", "oranges", "pineapple");
fruitArray  =  array( "apple", "oranges", "pineapple");
letters     =  array( 'a', 'b', 'c');
bytes       =  array( new byte[]{0x1, 0x2, 0x3, 0x4});

Существуют даже методы создания карт и сортированных карт, называемых map, sortedMap, safeMap (одновременный) и sortedSafeMap (одновременный). Они были созданы главным образом потому, что Java не имеет литералов для списков, карт и т.д.

Java: используйте оператор карты для создания SortedMap и карты

 favoritesMap = sortedMap(
      2, "pineapple",
      1, "oranges",
      3, "apple"
 );


 map =    map (
    "pineapple",  2,
    "oranges",    1,
    "apple",      3
 );

Вы можете индексировать карты, списки, массивы и т.д. с помощью оператора idx.

Java: использование оператора idx Boon Java для получения значений с индексом

 //Using idx to access a value.

 assert idx( veggiesSet, "b").equals("broccoli");

 assert idx( fruitList, 1 ).equals("oranges");

 assert idx( fruitArray, 1 ).equals("oranges");

 assert idx( letters, 1 ) == 'b';

 assert idx( bytes, 1 )      == 0x2;

 assert idx( favoritesMap, 2 ).equals("pineapple");

 assert idx( map, "pineapple" )  == 2;

Операторы idx также работают с отрицательными индексами.

Java: использование idx-оператора с отрицательными значениями

         //Negative indexes

          assert idx( fruitList, -2 ).equals("oranges");

          assert idx( fruitArray, -2 ).equals("oranges");

          assert idx( letters, -2 ) == 'b';

          assert idx( bytes, -3 )   == 0x2;

Ruby, Groovy и Python имеют эту функцию. Теперь вы можете использовать это и в Java! Версия Java (Boon) работает с примитивными массивами, поэтому вы не получаете автоматического бокса.

Что-то, что Ruby и Python не имеют, это нотация среза для SortedSets и SortedMaps. Вы можете использовать нотацию фрагментов для поиска отсортированных карт и отсортированных наборов в Java

Обозначения фрагментов работают с отсортированными картами и отсортированными наборами.

Вот пример, который объединяет несколько понятий.

          set = sortedSet("apple", "kiwi", "oranges", "pears", "pineapple")

          slcEnd( set, "o" )      //returns ("oranges", "pears", "pineapple")
          slc( set, "ap", "o" )   //returns ("apple", "kiwi"),
          slc( set, "o" )         //returns ("apple", "kiwi")

Вы действительно занимаетесь сортировкой отсортированных карт, а отсортированные наборы - это промежуточный запрос. Какой предмет появляется после "pi" ?

          after(set, "pi") //pineapple

И до ананаса?

          before(set, "pi")

Хорошо, пропустите его шаг за шагом....

  NavigableSet<String> set =
          sortedSet("apple", "kiwi", "oranges", "pears", "pineapple");

  assertEquals(

          "oranges", idx(set, "ora")

  );

Помните: TreeSet реализует NavigableSet и SortedSet.

Это было получено из моего блога....

http://rick-hightower.blogspot.com/2013/10/java-slice-notation-to-split-up-strings.html

Другие примеры.

Я получил некоторые из формулировок из этого обсуждения нарезания Python.

Объяснить нотацию фрагмента Python

Вот ссылка проекта Boon:

https://github.com/RichardHightower/boon

Теперь откройте SLICE!

Мы можем найти первый фрукт в наборе, который начинается с 'o', используя:

idx(set, "o")

Вот с набором фруктов, которые мы создали ранее (набор - это TreeSet с "яблоком", "киви", "апельсины", "груши", "ананас" ).

      assertEquals(

          "oranges", idx(set, "o")

      );

Мы нашли апельсины!

Здесь снова, но на этот раз мы ищем плоды, начинающиеся с "p", т.е. idx (set, "p" ).

      assertEquals(
          "pears",
          idx(set, "p")
      );

Да! Мы нашли груши!

Как насчет плодов, начинающихся с "пи" , как "ананас" - idx (set, "pi" )

  assertEquals(
          "pineapple",
          idx(set, "pi")
  );

Вы также можете запросить элемент, который находится после другого элемента. Что после "пи" ? после (set, "pi" )

  assertEquals(

          "pineapple",
          after(set, "pi")

  );

"Ананас" после пункта "пи" . после и idx одинаковы. Так почему я добавил после? Так что я могу иметь раньше!:) Что, если вы хотите знать, что есть до "pi" ?

before (set, "pi" )

  assertEquals(

          "pears",
          before(set, "pi")

  );

Как насчет всех плодов, которые находятся между "ap" и "o" ? Как я и обещал, есть нотация фрагмента!

slc (set, "ap", "o" )

  assertEquals(

          sortedSet("apple", "kiwi"),
          slc(set, "ap", "o")

  );

Как насчет всех плодов после "о" ?

slc (set, "o" )

  assertEquals(

          sortedSet("apple", "kiwi"),
          slc(set, "o")

  );

Итак, все фрукты после "о" - это "яблоко" и "киви".

Как насчет всех плодов до "о" ? (slcEnd читает его, пока я отрезвляю его.)

slcEnd (set, "o" )

  assertEquals(

          sortedSet("oranges", "pears", "pineapple"),
          slcEnd(set, "o")
  );

Таким образом, все плоды вплоть до "o" включают "апельсины", "груши" и "ананас" .

Безопасная нарезка для списка, подобного вещам

Эти операторы генерируют исключение, если индекс за пределами границ:

Обозначение фрагмента Java следующим образом с помощью Boon:

      ix( index )         // index of item
      zlc( a, start, end ) // items start through end-1
      zlc( a, start )      // items start through the rest of the array
      zlcEnd( a, end )     // items from the beginning through end-1

zlc обозначает нулевой сегмент допуска ix обозначает индекс нулевой точности zlcEnd обозначает нулевой сегмент конца допуска. копия означает "хорошо", "ошибка", "копия", конечно,

Мальчики и девочки... не забывайте всегда выполнять безопасную нарезку с предметами, которые вы не знаете.

Работает с примитивами, поэтому автоматическое боксирование

Индексирующие примитивы

 byte[] letters =
      array((byte)'a', (byte)'b', (byte)'c', (byte)'d');

 assertEquals(
      'a',
      idx(letters, 0)
 );


 assertEquals(
      'd',
      idx(letters, -1)
 );


 assertEquals(
      'd',
      idx(letters, letters.length - 1)
 );

 idx(letters, 1, (byte)'z');

 assertEquals(
      (byte)'z',
      idx(letters, 1)
 );

Метод len и idx являются универсальными операторами, и они работают над списками, массивами, наборами, картами и т.д.

len дайте мне длину подобной массиву, похожего на список, похожего на карту, предмета. idx дайте мне элемент в месте "индекса" в подобном массиву, похожий на список, похожий на карту, вещь.

HOME MC String Slice!

Вот несколько примеров резки строк Java Boon

  String letters = "abcd";

  boolean worked = true;

  worked &=

          idx(letters, 0)  == 'a'
                  || die("0 index is equal to a");



  worked &=

          idx(letters, -1)  == 'd'
                  || die("-1 index is equal to a");

Другой способ выражения idx (буквы, -1) == 'd' - idx (буквы, letters.length() - 1) == 'd'! Я предпочитаю более короткий путь!

  worked &=

          idx(letters, letters.length() - 1) == 'd'
                   || die("another way to express what the -1 means");


  //We can modify too
  letters = idx(letters, 1, 'z');

  worked &=

          idx(letters, 1) == 'z'
                  || die("Set the 1 index of letters to 'z'");


  worked &= (
          in('a', letters) &&
          in('z', letters)
  ) || die("'z' is in letters and 'a' is in letters");

Slice Slice Baby!

  letters = "abcd";

  worked &=
          slc(letters, 0, 2).equals("ab")
              || die("index 0 through index 2 is equal to 'ab'");



  worked &=
          slc(letters, 1, -1).equals("bc")
                  || die("index 1 through index (length -1) is equal to 'bc'");


  worked &=
          slcEnd(letters, -2).equals("ab")
                  || die("Slice of the end of the string!");


  worked &=
          slcEnd(letters, 2).equals("ab")
                  || die("Vanilla Slice Slice baby!");

Перевернувшись в моем 5.0, я получил свою тряпку сверху, чтобы мои волосы могли взорваться! Slice Slice Baby!!!

Ответ 3

Apache commons-lang поддерживает некоторую поддержку в StringUtils:

Получает подстроку из указанных исключений, исключающих String.

Отрицательная начальная позиция может использоваться для запуска n символов из конца строки

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

Ответ 4

Вы можете легко написать такой метод, помните, что отрицательные индексы вычитаются из длины строки, чтобы получить правильный индекс.

public String slice(String s, int start) {
   if (start < 0) start = s.length() + start; 

   return s.substring(start);
}

Ответ 5

используйте substring:

class Main
{
  public static void main (String[] args) throws java.lang.Exception
  {
     String s = new String("hello world");
     System.out.println(s.substring(0, s.length()));
     System.out.println(s.substring(s.length() - 1, s.length()));
     System.out.println(s.substring(3, 4));
  }
}

или charAt:

System.out.println(s.charAt(s.length() - 1));
System.out.println(s.charAt(3));

Java не является питоном, поэтому следует избегать отрицательного индекса, чтобы поддерживать постоянство. Однако вы можете сделать простую функцию преобразования.

Ответ 6

Я думаю, что нет такой Java-библиотеки строк, предоставляющей точно то же самое, что и python. Вероятно, самое лучшее, что вы можете сделать, - это создать новый класс, который предоставляет нужные вам функции. Поскольку String в java - это последний класс, из которого вы не можете расширить класс, вам нужно использовать композицию. Например:

public class PythonString {
  protected String value;
  public PythonString(String str) {
    value = new String(str);
  }

  public char charAt(int index) {
    if (index < 0) {
      return value.charAt(value.length() + index);
    }
    return value.charAt(index);
  }

  ....

}

Другой альтернативой является создание статической библиотеки строк.

Ответ 7

У меня есть простая библиотека, которая называется JavaSlice, которая дает единый способ доступа к фрагментам String, List или массивы на Java, аналогично Python.

Итак, ваши примеры будут просто записаны следующим образом:

    String sample = "hello world";

    System.out.println(slice(sample, 0, -1)); // "hello worl"
    System.out.println(slice(sample, -1)); // 'd'
    System.out.println(slice(sample, 3)); // 'l'

Ответ 8

Простой ответ, нет. Строки неизменны на обоих языках. Строки внутренне хранятся в виде массивов символов, поэтому использование подстроки и использование скобок в Python по сути делают то же самое. Java не поддерживает перегрузку оператора, поэтому нет возможности предоставить эту функциональность языку. Использование подстроки не так уж плохо. Вы не должны делать это слишком часто. Вы всегда можете писать вспомогательные функции, если вы делаете это очень часто, чтобы упростить свое использование.