Скільки пробілів буде видалено Java String.trim ()?


117

У Java у мене є такий рядок:

"     content     ".

Чи буде String.trim()видалено всі пробіли з цих боків або лише один пробіл на кожному?


197
Для супротивників: ваша поведінка поблажлива. Це питання детальне та конкретне, написане чітко і просто, що цікавить хоча б одного програміста десь. Люди можуть не знати, де шукати, щоб знайти javadoc або вихідний код. Наша робота - допомогти їм, а не засуджувати їх за неосвіченість.
glmxndr

14
@subtenante, ти маєш рацію. Я навіть захищав людей, які раніше задавали питання google'ish. Однак щось таке просте, як це слід перевірити самостійно, і ІМО, НІКОЛИ НЕ БУДЕ дозволено розміщувати питання на веб-сайті з питань запитання. Заголовок вводить в оману, а Q - це марна трата часу для всіх, хто його читає.
Кріс

9
@Chris: oneat дав мені нагоду подивитися вихідний код. Я багато чого дізнався про обробку (). У мене не було б інакше. Кожен несе відповідальність за власні витрати свого часу. oneat не винен у тому, що ми не змогли отримати прибуток від свого, здавалося б, наївного питання.
glmxndr

1
@skaffman: (c) слід "спробувати і подивитись", і лише потім (d) запитати про ТАК.
Мак

2
Це питання видається поза темою, оскільки мова йде про те, що хтось повинен мати змогу знайти в посібнику І тестування протягом менше хвилини.
Джаспер

Відповіді:


168

Усі вони .

Повертає : копія цього рядка з вилученим проміжним проміжним білим пробілом або цього рядка, якщо він не має провідного або останнього пробілу.

~ Цитується з Java 1.5.0 документів

(Але чому ти просто не спробував це і переконався?)


1
Мені довелося проголосувати, оскільки ця відповідь не стосується того, що документація означає "пробіл". Здавалося б, логічно, що це було б там, де Chararacter.isWhitespaceце правда, але це не те, що означає "пробіл" ..
user2864740

7
@ User2864740: Ця відповідь не претендує на всебічний аналіз trim, і isWhiteSpaceт.д., або обговорення неясностей в документації Java; це пряма відповідь на конкретне запитання, задане вище - тобто trimметод видаляє один простір або кілька пробілів?
ЛукаХ

Я знаю, що це не так. Я проголосував за те, що не вдається вказати на таке, навіть мимохідь. У будь-якому випадку я не можу скасувати свій голос, якщо він не оновлюється (але мінімально).
user2864740

33

З вихідного коду (декомпілюється):

  public String trim()
  {
    int i = this.count;
    int j = 0;
    int k = this.offset;
    char[] arrayOfChar = this.value;
    while ((j < i) && (arrayOfChar[(k + j)] <= ' '))
      ++j;
    while ((j < i) && (arrayOfChar[(k + i - 1)] <= ' '))
      --i;
    return (((j > 0) || (i < this.count)) ? substring(j, i) : this);
  }

Два, whileякі ви можете бачити, означають, що всі символи, унікод яких знаходиться нижче символу пробілу, на початку та в кінці, видаляються.


27

Якщо ви сумніваєтесь, напишіть одиничний тест:

@Test
public void trimRemoveAllBlanks(){
    assertThat("    content   ".trim(), is("content"));
}

Примітка : звичайно, тест (для JUnit + Hamcrest) не провалюється


43
Запитайте нового програміста, який щойно навчився робити System.out.println, щоб зробити тест на одиницю, щоб побачити, який результат ...
jaxkodex

26

Однак слід зазначити, що String.trim має своєрідне визначення поняття "пробіл". Він не видаляє пробіл Unicode, але також видаляє символи управління ASCII, які ви можете не вважати пробілами.

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

Якщо можливо, ви можете скористатися StringUtils.strip () Commons Lang, який також обробляє пробіл Unicode (і також є безпечним для нуля).


3
Здається, жахливий нагляд з боку дизайнерів .. і надзвичайно технічна робота з документацією не дуже допомагає.
користувач2864740

2
Браво! Ви взяли найпростіше запитання, яке коли-небудь задавали на StackOverflow, і знайшли щось розумне, щоб сказати на це питання. Ти заслуга гонки.
Марк Маккенна

3
@MarkMcKenna: Я постійно констатую, що ці нібито надпрості запитання щодо програмування (обрізка рядків, пошук розширень імен файлів тощо) завжди мають свої приховані складності. Це трохи розчаровує наше ремесло та інструменти.
Тіло

15

Дивіться клас API для рядка:

Повертає копію рядка з пропущеним пробілом та пробілом.

Пробіл з обох сторін видалено:

Зауважте, що trim()не змінюється екземпляр String, він поверне новий об'єкт:

 String original = "  content  ";
 String withoutWhitespace = original.trim();

 // original still refers to "  content  "
 // and withoutWhitespace refers to "content"

1
насправді ніщо не може змінити екземпляр String (крім деяких брудних речей, які можуть
зірвати

13

Грунтуючись на документах Java тут , .trim()замінює "\ u0020", який зазвичай називають пробілом.

Але врахуйте, що "\ u00A0" ( Unicode NO-BREAK SPACE &nbsp; ) також розглядається як пробіл, і.trim() НЕ буде видаляти це. Це особливо часто в HTML.

Щоб видалити його, я використовую:

tmpTrimStr = tmpTrimStr.replaceAll("\\u00A0", "");

Приклад цієї проблеми обговорювався тут .


На основі Javadoc він видаляє пробіли проміжних та кінцевих пробілів, що включає пробіл, вкладку, повернення каретки в новому рядку , подачу форми, ... і який виключає символи, які не є ведучими або неперехідними.
Маркіз Лорн

Дякую, це допомагає мені виділити
Асад Хайдер

8

Приклад trim()видалення пробілів Java :

public class Test
{
    public static void main(String[] args)
    {
        String str = "\n\t This is be trimmed.\n\n";

        String newStr = str.trim();     //removes newlines, tabs and spaces.

        System.out.println("old = " + str);
        System.out.println("new = " + newStr);
    }
}

ВИХІД

old = 
 This is a String.


new = This is a String.

4

З документів Java (джерело класу String),

/**
 * Returns a copy of the string, with leading and trailing whitespace
 * omitted.
 * <p>
 * If this <code>String</code> object represents an empty character
 * sequence, or the first and last characters of character sequence
 * represented by this <code>String</code> object both have codes
 * greater than <code>'&#92;u0020'</code> (the space character), then a
 * reference to this <code>String</code> object is returned.
 * <p>
 * Otherwise, if there is no character with a code greater than
 * <code>'&#92;u0020'</code> in the string, then a new
 * <code>String</code> object representing an empty string is created
 * and returned.
 * <p>
 * Otherwise, let <i>k</i> be the index of the first character in the
 * string whose code is greater than <code>'&#92;u0020'</code>, and let
 * <i>m</i> be the index of the last character in the string whose code
 * is greater than <code>'&#92;u0020'</code>. A new <code>String</code>
 * object is created, representing the substring of this string that
 * begins with the character at index <i>k</i> and ends with the
 * character at index <i>m</i>-that is, the result of
 * <code>this.substring(<i>k</i>,&nbsp;<i>m</i>+1)</code>.
 * <p>
 * This method may be used to trim whitespace (as defined above) from
 * the beginning and end of a string.
 *
 * @return  A copy of this string with leading and trailing white
 *          space removed, or this string if it has no leading or
 *          trailing white space.
 */
public String trim() {
int len = count;
int st = 0;
int off = offset;      /* avoid getfield opcode */
char[] val = value;    /* avoid getfield opcode */

while ((st < len) && (val[off + st] <= ' ')) {
    st++;
}
while ((st < len) && (val[off + len - 1] <= ' ')) {
    len--;
}
return ((st > 0) || (len < count)) ? substring(st, len) : this;
}

Зауважте, що після початку та довжини він викликає метод підрядки класу String.


Де "пробіл" - це "символи зі значеннями, меншими або рівними \ x20" .. бурхливими.
користувач2864740

3

trim()видалить усі провідні та кінцеві заготовки. Але майте на увазі: ваш рядок не змінено. trim()поверне замість нього новий екземпляр рядка.


Це видалить усі провідні та відсталі пробіли.
Маркіз Лорн

3

Якщо ваш рядковий вхід:

String a = "   abc   ";
System.out.println(a);

Так, вихід буде "abc"; Але якщо ваш вхід String:

String b = "    This  is  a  test  "
System.out.println(b);

Вихід буде таким This is a test чином обрізка видаляє лише пробіли перед першим символом та після останнього символу в рядку та ігнорує внутрішні пробіли. Це фрагмент мого коду, який трохи оптимізує вбудований Stringметод обрізки, видаляючи внутрішні пробіли та видаляє пробіли до та після першого та останнього символу рядка. Сподіваюся, це допомагає.

public static String trim(char [] input){
    char [] output = new char [input.length];
    int j=0;
    int jj=0;
    if(input[0] == ' ' )    {
        while(input[jj] == ' ') 
            jj++;       
    }
    for(int i=jj; i<input.length; i++){
      if(input[i] !=' ' || ( i==(input.length-1) && input[input.length-1] == ' ')){
        output[j]=input[i];
        j++;
      }
      else if (input[i+1]!=' '){
        output[j]=' ';
        j++;
      }      
    }
    char [] m = new char [j];
    int a=0;
    for(int i=0; i<m.length; i++){
      m[i]=output[a];
      a++;
    }
    return new String (m);
  }

Перша пара тверджень у цій відповіді явно неправильна, вихід не буде "abc". Можливо, ви забули .trim()в System.out.println(a);?
Ар’ян


2

Одне дуже важливе - це те, що рядок, повністю створений з "білих пробілів", поверне порожню рядок.

якщо a string sSomething = "xxxxx", де xстоїть пробіл, sSomething.trim()поверне порожню рядок.

якщо a string sSomething = "xxAxx", де xстоять пробіли, sSomething.trim()повернеться A.

якщо sSomething ="xxSomethingxxxxAndSomethingxElsexxx", sSomething.trim()повернеться SomethingxxxxAndSomethingxElse, зверніть увагу , що число xміж словами не змінюється.

Якщо ви хочете, щоб акуратний пакетний рядок поєднувався trim()з регулярним виразом, як показано в цій публікації: Як видалити повторювані пробіли в рядку за допомогою Java? .

Порядок безглуздий для результату, але trim()спочатку був би більш ефективним. Сподіваюся, це допомагає.


2

Щоб зберегти лише один екземпляр для String, ви можете використовувати наступне.

str = "  Hello   ";

або

str = str.trim();

Тоді значення strString, будеstr = "Hello"



0

Javadoc for String має всі деталі. Видаляє пробіл (пробіл, вкладки тощо) з обох кінців і повертає нову рядок.


0

Якщо ви хочете перевірити, що буде робити якийсь метод, ви можете скористатися BeanShell . Це мова сценаріїв, покликана максимально наблизитися до Java. Взагалі, це тлумачить Ява з деякими розслабленнями. Ще один варіант такого роду - Groovy мова. Обидві ці мови сценаріїв забезпечують зручне знання циклу Read-Eval-Print з інтерпретованих мов. Таким чином, ви можете запустити консоль і просто ввести:

"     content     ".trim();

Ви побачите "content"результат після натискання Enter(або Ctrl+Rв консолі Groovy).


6
Отже, щоб зрозуміти метод на Java, йому слід вивчити абсолютно нову мову. Дійсно?
james.garriss

0
String formattedStr=unformattedStr;
formattedStr=formattedStr.trim().replaceAll("\\s+", " ");

Це не пов’язано з питанням.
Марк Маккенна

2
@ Марк, але випадково це було те, що я шукав, коли відкрив це питання ...
Armfoot

Це також безглуздо. trim()вже робить те, що repkaceAll()зробив би, якби для цього було щось.
Маркіз Лорн

@EJP the substituAll також замінить пробіли в рядку на єдиний пробіл, а обробка буде обробляти лише провідні та кінцеві пробіли
Krishna
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.