Java, как заменить 2 или более пробелов одним пробелом в строке и удалить начальные и конечные пробелы


271

Ищете быстрый и простой способ в Java, чтобы изменить эту строку

" hello     there   "

что-то похожее на это

"hello there"

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

Нечто подобное заставляет меня там отчасти

String mytext = " hello     there   ";
mytext = mytext.replaceAll("( )+", " ");

но не совсем.


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

1
Это один из самых рекомендуемых способов. => String nameWithProperSpacing = StringUtils.normalizeSpace (stringWithLotOfSpaces);
Кунал Вохра

s = s.replaceAll ("\\ s +", "");
Сародж Кумар Саху

Ответы:


462

Попробуй это:

String after = before.trim().replaceAll(" +", " ");

Смотрите также


Нет trim()регулярных выражений

Это также возможно сделать только с одним replaceAll, но это гораздо менее читабельно, чем trim()решение. Тем не менее, здесь приведено только для того, чтобы показать, что может сделать регулярное выражение:

    String[] tests = {
        "  x  ",          // [x]
        "  1   2   3  ",  // [1 2 3]
        "",               // []
        "   ",            // []
    };
    for (String test : tests) {
        System.out.format("[%s]%n",
            test.replaceAll("^ +| +$|( )+", "$1")
        );
    }

Есть 3 варианта:

  • ^_+ : любая последовательность пробелов в начале строки
    • Сопоставьте и замените с $1, который захватывает пустую строку
  • _+$ : любая последовательность пробелов в конце строки
    • Сопоставьте и замените с $1, который захватывает пустую строку
  • (_)+ : любая последовательность пробелов, которая не соответствует ни одному из вышеперечисленных, то есть она находится в середине
    • Подберите и замените на $1, который захватывает один пробел

Смотрите также


11
+1, тем более, что стоит отметить, что делать, trim()а затем replaceAll()использовать меньше памяти, чем делать это наоборот. Не очень, но если это вызывается много-много раз, это может сложиться, особенно если есть много «обрезаемых пробелов». (на Trim()самом деле не избавляется от лишнего пространства - он просто скрывает его, перемещая начальное и конечное значения. Базовое значение char[]остается неизменным.)
corsiKa

2
Это всего лишь деталь, но я думаю, что ( ) +или ( ){2,}должен быть (очень) немного более эффективным;)
sp00m

6
Хорошее регулярное выражение Примечание: замена пробела `` \\sзаменяет любую группу пробелов на нужный символ.
djmj

1
Обратите внимание, что часть () + будет соответствовать одному пробелу и заменить его одним пробелом. Возможно, (<пробел> <пробел> +) было бы лучше, поэтому он совпадает только в том случае, если есть несколько пробелов и замена приведет к чистому изменению строки.
Ли Меадор

2
Как отметил Ли Меадор, .trim().replaceAll(" +", " ")(с двумя пробелами) быстрее, чем .trim().replaceAll(" +", " ")(с одним пробелом). Я запускал временные тесты для строк, которые имели только один пробел и все двойные пробелы, и он выполнялся значительно быстрее для обеих операций при выполнении большого количества операций (миллионы или больше, в зависимости от среды).
Гэри С. Уивер

154

Вам просто нужно:

replaceAll("\\s{2,}", " ").trim();

где вы сопоставляете один или несколько пробелов и заменяете их одним пробелом, а затем обрезаете пробелы в начале и в конце (вы можете фактически инвертировать, сначала обрезав, а затем сопоставив, чтобы сделать регулярное выражение быстрее, как кто-то указал).

Чтобы проверить это быстро, попробуйте:

System.out.println(new String(" hello     there   ").trim().replaceAll("\\s{2,}", " "));

и он вернется:

"hello there"

3
Я, вероятно, сначала урежу, потому что тогда вы сохраняете регулярное выражение в работе.
Майкл

3
@ sarah.ferguson Пожалуйста, удалите последнюю скобку ")", которой не должно быть в первой замене. Спасибо. - Система не позволит мне сделать это! (
Только

2
Обратите внимание, что это заменяет один пробел другим пробелом в случае, когда нет нескольких пробелов вместе. В этом случае нет необходимости выполнять замену, хотя вы можете этого захотеть, поскольку вы заменяете одну вкладку одним пробелом. Было бы неплохо распознавать только несколько пробелов.
Ли Меадор

2
@geowar, где вопрос задал вкладки извините? Я уверен, что вышеупомянутое не заменяет ☮ символов, а также matter ...
sarah.ferguson

2
подождите секунду @geowar Это заменит одну таблицу с пробелом. Я только что попробовал
user1870400


20

Это отлично сработало для меня: sValue = sValue.trim().replaceAll("\\s+", " ");


1
Люди отредактировали мой ответ. Оригинал был: sValue = sValue.replaceAll ("\ s +", "") .trim ();
Доктор

2
Отредактировано потому, что ваш первоначальный ответ удаляет все пробелы, и это не то, что спросил ОП
Хосе Руи Сантос

17
"[ ]{2,}"

Это будет соответствовать более чем одному пробелу.

String mytext = " hello     there   ";
//without trim -> " hello there"
//with trim -> "hello there"
mytext = mytext.trim().replaceAll("[ ]{2,}", " ");
System.out.println(mytext);

ВЫВОД:

hello there

13

Чтобы исключить пробелы в начале и в конце строки, используйте String#trim()метод. А потом используй свой mytext.replaceAll("( )+", " ").


12

Вы можете сначала использовать String.trim(), а затем применить команду regex replace к результату.


10
trim () удалит все пробелы в начале и конце строки, это не относится к
пробелу

10

Следующий код сжимает любые пробелы между словами и удаляет любые в начале и конце строки

String input = "\n\n\n  a     string with     many    spaces,    \n"+
               " a \t tab and a newline\n\n";
String output = input.trim().replaceAll("\\s+", " ");
System.out.println(output);

Это будет выводить a string with many spaces, a tab and a newline

Обратите внимание, что любые непечатаемые символы, включая пробелы, символы табуляции и переносы строк, будут сжаты или удалены


Для получения дополнительной информации см. Соответствующую документацию:


9

Попробуй это.

Образец кода

String str = " hello     there   ";
System.out.println(str.replaceAll("( +)"," ").trim());

ВЫВОД

hello there

Сначала он заменит все пробелы одним пробелом. Чем мы должны делать обрезку, Stringпотому что в начале Stringи конце Stringона заменит все пробелы одним пробелом, если Stringесть пробелы в начале Stringи конце, Stringпоэтому нам нужно их обрезать. Чем вы получаете желаемое String.


4

Вы могли бы также использовать lookarounds.

test.replaceAll("^ +| +$|(?<= ) ", "");

ИЛИ

test.replaceAll("^ +| +$| (?= )", "")

<space>(?= )соответствует пробелу, за которым следует другой пробел. Таким образом, в последовательных пробелах он будет соответствовать всем пробелам, кроме последнего, потому что за ним не следует пробел. Это оставляет вам один пробел для последовательных пробелов после операции удаления.

Пример:

    String[] tests = {
            "  x  ",          // [x]
            "  1   2   3  ",  // [1 2 3]
            "",               // []
            "   ",            // []
        };
        for (String test : tests) {
            System.out.format("[%s]%n",
                test.replaceAll("^ +| +$| (?= )", "")
            );
        }

Как у вас есть, он будет совпадать с любым пробелом на фронте или конце или любым другим пробелом с другим пробелом после него. Это означает, что "a .... b" будет соответствовать 3 раза и заменять три раза. Он перебирает все внутренние пространства внутри метода replaceAll (). Возможно, вы могли бы изменить его так, чтобы он соответствовал любой последовательности из 2 или более пробелов одновременно и уменьшал внутреннюю итерацию.
Ли Меадор

Может быть, <пробел> + (? = <Пробел>) сделает это.
Ли Меадор

4

отделка()

Удаляет только начальные и конечные пробелы.

Из Java Doc «Возвращает строку, значением которой является эта строка, с удалением всех начальных и конечных пробелов».

System.out.println(" D ev  Dum my ".trim());

"D ev Dum my"

replace (), replaceAll ()

Заменяет все пустые строки в слове,

System.out.println(" D ev  Dum my ".replace(" ",""));

System.out.println(" D ev  Dum my ".replaceAll(" ",""));

System.out.println(" D ev  Dum my ".replaceAll("\\s+",""));

Вывод:

"DevDummy"

"DevDummy"

"DevDummy"

Примечание: "\ s +" - это регулярное выражение, похожее на символ пробела.

Ссылка : https://www.codedjava.com/2018/06/replace-all-spaces-in-string-trim.html


4

До сих пор было дано много правильных ответов, и я вижу много голосов. Тем не менее, упомянутые способы будут работать, но не очень оптимизированы или не очень читабельны. Недавно я наткнулся на решение, которое понравится каждому разработчику.

String nameWithProperSpacing = StringUtils.normalizeSpace( stringWithLotOfSpaces );

Вы сделали. Это читабельное решение.


3

В Котлине это будет выглядеть так

val input = "\n\n\n  a     string with     many    spaces,    \n"
val cleanedInput = input.trim().replace(Regex("(\\s)+"), " ")

2
String str = " hello world"

уменьшить пробелы в первую очередь

str = str.trim().replaceAll(" +", " ");

заглавная буква и строчные все остальное

str = str.substring(0,1).toUpperCase() +str.substring(1,str.length()).toLowerCase();

2
mytext = mytext.replaceAll("\\s+"," ");

Ответы только на код не приветствуются. Пожалуйста, нажмите на изменить и добавьте несколько слов, обобщающих, как ваш код решает вопрос, или, возможно, объясните, чем ваш ответ отличается от предыдущих ответов. Спасибо
Ник

1

Это сработало для меня

scan= filter(scan, " [\\s]+", " ");
scan= sac.trim();

где фильтр - следующая функция, а сканирование - входная строка:

public String filter(String scan, String regex, String replace) {
    StringBuffer sb = new StringBuffer();

    Pattern pt = Pattern.compile(regex);
    Matcher m = pt.matcher(scan);

    while (m.find()) {
        m.appendReplacement(sb, replace);
    }

    m.appendTail(sb);

    return sb.toString();
}

1
Это заменит <пробел> <tab> пробелом, но не <tab> <tab>. Кажется, это небольшая проблема.
Ли Меадор

1

ты должен сделать это так

String mytext = " hello     there   ";
mytext = mytext.replaceAll("( +)", " ");

поставить + внутри круглых скобок.



0

См String.replaceAll.

Используйте регулярное выражение "\s"и замените на " ".

Тогда используйте String.trim.


1
new String ("hello there") .replaceAll ("\\ s", "+") возвращает + hello +++++++ там +++, поэтому определенно не работает ..
sarah.ferguson

1
Попробуйтеnew String(" hello there ").trim().replaceAll("\\s+", " ")
manish_s

0

Проверь это...

public static void main(String[] args) {
    String s = "A B  C   D    E F      G\tH I\rJ\nK\tL";
    System.out.println("Current      : "+s);
    System.out.println("Single Space : "+singleSpace(s));
    System.out.println("Space  count : "+spaceCount(s));
    System.out.format("Replace  all = %s", s.replaceAll("\\s+", ""));

    // Example where it uses the most.
    String s = "My name is yashwanth . M";
    String s2 = "My nameis yashwanth.M";

    System.out.println("Normal  : "+s.equals(s2));
    System.out.println("Replace : "+s.replaceAll("\\s+", "").equals(s2.replaceAll("\\s+", "")));

} 

Если строка содержит только один пробел, то replace () не будет заменять,

Если пробелов больше, чем один, выполняется действие replace (), которое удаляет процедуру.

public static String singleSpace(String str){
    return str.replaceAll("  +|   +|\t|\r|\n","");
}

Подсчитать количество пробелов в строке.

public static String spaceCount(String str){
    int i = 0;
    while(str.indexOf(" ") > -1){
      //str = str.replaceFirst(" ", ""+(i++));
        str = str.replaceFirst(Pattern.quote(" "), ""+(i++)); 
    }
    return str;
}

Pattern .quote ("?") Возвращает буквенный шаблон String.


0

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

private String replaceMultipleSpacesFromString(String s){
    if(s.length() == 0 ) return "";

    int timesSpace = 0;
    String res = "";

    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);

        if(c == ' '){
            timesSpace++;
            if(timesSpace < 2)
                res += c;
        }else{
            res += c;
            timesSpace = 0;
        }
    }

    return res.trim();
}

Интересно, но пустое пространство означает больше, чем просто пробелы.
Лаур Иван

@LaurIvan что ты имеешь ввиду?
trinity420

эта запись имеет хорошее объяснение того, что \sозначает регулярные выражения (пробел, табуляция, новая строка, подача формы).
Лаур Иван

@LaurIvan Ваша ссылка не работает, но вы правы. Я думаю, что эту проблему можно решить путем перебора входной строки, удалив все не алфавитные, не числовые и не пробельные символы.
trinity420

0

Потоковая версия, фильтры пробелов и вкладок.

Stream.of(str.split("[ \\t]")).filter(s -> s.length() > 0).collect(Collectors.joining(" "))

0
String myText = "   Hello     World   ";
myText = myText.trim().replace(/ +(?= )/g,'');


// Output: "Hello World"

0

Самый простой метод для удаления пробелов в любом месте строки.

 public String removeWhiteSpaces(String returnString){
    returnString = returnString.trim().replaceAll("^ +| +$|( )+", " ");
    return returnString;
}

-1
public class RemoveExtraSpacesEfficient {

    public static void main(String[] args) {

        String s = "my    name is    mr    space ";

        char[] charArray = s.toCharArray();

        char prev = s.charAt(0);

        for (int i = 0; i < charArray.length; i++) {
            char cur = charArray[i];
            if (cur == ' ' && prev == ' ') {

            } else {
                System.out.print(cur);
            }
            prev = cur;
        }
    }
}

Приведенное выше решение представляет собой алгоритм со сложностью O (n) без использования какой-либо Java-функции.


-1

Пожалуйста, используйте ниже код

package com.myjava.string;

import java.util.StringTokenizer;

public class MyStrRemoveMultSpaces {

    public static void main(String a[]){

        String str = "String    With Multiple      Spaces";

        StringTokenizer st = new StringTokenizer(str, " ");

        StringBuffer sb = new StringBuffer();

        while(st.hasMoreElements()){
            sb.append(st.nextElement()).append(" ");
        }

        System.out.println(sb.toString().trim());
    }
}

-1

Привет, извините за задержку! Вот лучший и самый эффективный ответ, который вы ищете:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MyPatternReplace {

public String replaceWithPattern(String str,String replace){

    Pattern ptn = Pattern.compile("\\s+");
    Matcher mtch = ptn.matcher(str);
    return mtch.replaceAll(replace);
}

public static void main(String a[]){
    String str = "My    name    is  kingkon.  ";
    MyPatternReplace mpr = new MyPatternReplace();
    System.out.println(mpr.replaceWithPattern(str, " "));
}

Таким образом, ваш вывод этого примера будет: Меня зовут kingkon.

Однако этот метод также удалит "\ n", который может иметь ваша строка. Так что, если вы не хотите, просто используйте этот простой метод:

while (str.contains("  ")){  //2 spaces
str = str.replace("  ", " "); //(2 spaces, 1 space) 
}

И если вы хотите убрать начальные и конечные пробелы, просто добавьте:

str = str.trim();

-1

Я знаю, что метод replaceAll намного проще, но я также хотел опубликовать это.

public static String removeExtraSpace(String input) {
    input= input.trim();
    ArrayList <String> x= new ArrayList<>(Arrays.asList(input.split("")));
    for(int i=0; i<x.size()-1;i++) {
        if(x.get(i).equals(" ") && x.get(i+1).equals(" ")) { 
            x.remove(i); 
            i--; 
        }
    }
    String word="";
    for(String each: x) 
        word+=each;
    return word;
}

1
Хотя это работает, это далеко не самое простое решение.
Platzhersh

-1

Струнный токенизатор может быть использован

 String str = "  hello    there  ";
            StringTokenizer stknzr = new StringTokenizer(str, " ");
            StringBuffer sb = new StringBuffer();
            while(stknzr.hasMoreElements())
            {
                sb.append(stknzr.nextElement()).append(" ");
            }
            System.out.println(sb.toString().trim());
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.