Видаліть кілька пробілів


208

Я отримую $row['message']з бази даних MySQL, і мені потрібно видалити всі пробіли, подібні \n \tтощо.

$row['message'] = "This is   a Text \n and so on \t     Text text.";

має бути відформатовано до:

$row['message'] = 'This is a Text and so on Text text.';

Я намагався:

 $ro = preg_replace('/\s\s+/', ' ',$row['message']);
 echo $ro;

але він не видаляє \nабо \tпросто проміжки. Хтось може сказати мені, як це зробити?


1
Символи нового рядка та вкладок є в одній лапки, тож ви хочете, щоб вони були буквальними?
Марк Лалор

Я виправив котирування коду sectin з \ n і \ t, змінивши його на подвійні лапки.
Buttle Butkus

Відповіді:


394

Тобі потрібно:

$ro = preg_replace('/\s+/', ' ',$row['message']);

Ви використовуєте, \s\s+що означає пробіл (пробіл, вкладка чи новий рядок), а потім один чи більше пробілів. Що фактично означає замінити два або більше пробілів на один пробіл.

Що ви хочете, це замінити одне або кілька пробілів на простір пробілів, тож ви можете використовувати шаблон \s\s*або \s+(рекомендується)


1
його метод кращий за цей: чому б ви замінили один простір одним простором?
nickf

16
Він також хоче \ n і \ t замінити пробіл. Тепер його шаблон не відповідає цим, скажімо, для $ x = "робить \ nце \ t робота"; ОП хоче, щоб усі пробіли були замінені одним простором.
кодифікація

@codaddict, як ми можемо зберегти \ n та видалити всі інші множинні пробіли та вкладки з рядка? будь ласка, допоможіть мені
Мансоорхан Черупужа

Чи можете ви бути більш конкретними, чому рекомендується "\ s +"?
Ісій

6
Зауважте, що в PHP \sне включається "вертикальна вкладка" chr(11). Щоб також включити його, вам потрібно скористатися spaceкласом символів: [[:space:]]+ php.net/manual/en/regexp.reference.character-classes.php
Ярослав

68
<?php
$str = "This is  a string       with
spaces, tabs and newlines present";

$stripped = preg_replace(array('/\s{2,}/', '/[\t\n]/'), ' ', $str);

echo $str;
echo "\n---\n";
echo "$stripped";
?>

Це виводить

This is  a string   with
spaces, tabs and newlines present
---
This is a string with spaces, tabs and newlines present

3
Ви справжній рятівник. Я збирався вискочити, якщо вікно над цим.
bikey77

Акуратний, все ще корисний
spekulatius

16
preg_replace('/[\s]+/mu', ' ', $var);

\s вже містить вкладки та нові рядки, тому цього вище регексу видається достатнім.


2
Квадратні дужки тут не потрібні, оскільки всередині них лише одне. /mЗвичай мати ефект , як немає ^і $якоря , і /uне матиме ніякого ефекту , крім як уповільнити його трохи і померти , якщо вхідний рядок не є допустимим UTF-8 (це не впливає на те , що \sвідповідає, але це може вплинути \pZ).
thomasrutter

12

спрощена до однієї функції:

function removeWhiteSpace($text)
{
    $text = preg_replace('/[\t\n\r\0\x0B]/', '', $text);
    $text = preg_replace('/([\s])\1+/', ' ', $text);
    $text = trim($text);
    return $text;
}

на основі відповіді Дануеля О'Ніла.


7
$str='This is   a Text \n and so on Text text.';
print preg_replace("/[[:blank:]]+/"," ",$str);

2
Це той, який працював для мене найкраще. Також я б додав обрізки, щоб стерти пробіли на початку та в кінці рядка
Dziamid

@Dziamid Ви можете зробити це з обрізкою (preg_replace (...))
Balázs Varga

7

Я не можу повторити проблему тут:

$x = "this    \n \t\t \n    works.";
var_dump(preg_replace('/\s\s+/', ' ', $x));
// string(11) "this works."

Я не впевнений, це була лише помилка транскрипції чи ні, але у вашому прикладі ви використовуєте рядок з цитуванням. \nі \tрозглядаються як новий рядок та вкладка, лише якщо у вас є подвійний рядок з цитуванням. Це є:

'\n\t' != "\n\t"

Редагувати : як зазначає Кодація, \s\s+не замінить жодного символу вкладки. Я все ще не думаю, що використання \s+є ефективним рішенням, а як же це зробити:

preg_replace('/(?:\s\s+|\n|\t)/', ' ', $x);

2
+1, правда. Для рядка з великою кількістю одиничних пробілів (що зазвичай буває) замінити пробіл на пробіл неефективно.
кодифікація

1
@coaddict: щоб перевірити вашу гіпотезу, я написав швидкий сценарій, щоб пробігти 1000 замінників і перевірити терміни кожної. Для рядка '+1, True. Для рядка з великою кількістю одиничних пробілів (як правило, це так) неефективно замінити пробіл на пробіл. - кодифікація 24 лютого \ '10 о 13:32 ' , одна тисяча \ s + preg_replace () дзвінків зайняла 0,010547876358032 секунд, а одна тисяча (?: \ S \ s + | \ n | \ t) preg_replace () дзвінків зайняла 0,013049125671387, здійснюючи це майже на 30% повільніше.
Джозеф Щок

Ви можете додати "\ r" до цього останнього прикладу, оскільки деякі комп’ютери самостійно використовують один "\ r" (Apple Mac?)
thomasrutter

4
preg_replace('/(\s\s+|\t|\n)/', ' ', $row['message']);

Це замінює всі вкладки, всі нові рядки та всі комбінації декількох пробілів, вкладок та нових рядків одним пробілом.


4
<?php
#This should help some newbies
# REGEX NOTES FROM DANUEL
# I wrote these functions for my own php framework
# Feel Free to make it better
# If it gets more complicated than this. You need to do more software engineering/logic.
# (.)  // capture any character
# \1   // if it is followed by itself
# +    // one or more

class whitespace{

    static function remove_doublewhitespace($s = null){
           return  $ret = preg_replace('/([\s])\1+/', ' ', $s);
    }

    static function remove_whitespace($s = null){
           return $ret = preg_replace('/[\s]+/', '', $s );
    }

    static function remove_whitespace_feed( $s = null){
           return $ret = preg_replace('/[\t\n\r\0\x0B]/', '', $s);
    }

    static function smart_clean($s = null){
           return $ret = trim( self::remove_doublewhitespace( self::remove_whitespace_feed($s) ) );
    }
}
$string = " Hey   yo, what's \t\n\tthe sc\r\nen\n\tario! \n";
echo whitespace::smart_clean($string);

з якої причини статична функція remove_whitespace? Ви визначаєте, але ніколи не використовуєте його.
Лукас Лейсіс

Кожен з них має своє використання, але жодне з них не дозволить досягти того, що задається питанням - замінити кілька послідовних пробілів просто одним. Ваш "remove_doublewhitespace" замінить лише кілька однакових символів пробілу, тому він замінить "\ n \ n \ n" на ", але це не зробить нічого для" \ r \ n "
thomasrutter

4

Без preg_replace ()

$str = "This is   a Text \n and so on \t     Text text.";
$str = str_replace(["\r", "\n", "\t"], " ", $str);
while (strpos($str, "  ") !== false)
{
    $str = str_replace("  ", " ", $str);
}
echo $str;

2

Я використовую цей код і зразок:

preg_replace('/\\s+/', ' ',$data)

$data = 'This is   a Text 
   and so on         Text text on multiple lines and with        whitespaces';
$data= preg_replace('/\\s+/', ' ',$data);
echo $data;

Ви можете перевірити це на http://writecodeonline.com/php/


Він працює зі мною навіть у mariaDB в цьому запиті: SELECT search_able, REGEXP_REPLACE (search_able,"\\s+",' ') FROM book where id =260 Тож дякую
jalmatari

1

Все, що вам потрібно, це запустити його наступним чином:

echo preg_replace('/\s{2,}/', ' ', "This is   a Text \n and so on \t     Text text."); // This is a Text and so on Text text.

1

Це я б використовував:

а. Обов’язково використовуйте подвійні лапки, наприклад:

$row['message'] = "This is   a Text \n and so on \t     Text text.";

б. Щоб видалити зайвий пробіл, використовуйте:

$ro = preg_replace('/\s+/', ' ', $row['message']); 
echo $ro;

Це може бути не найшвидшим рішенням, але я думаю, що це вимагатиме найменшого коду, і воно має працювати. Я ніколи не використовував mysql, тому, можливо, я помиляюся.


1

По правді, якщо подумаєте, що ви хочете щось подібне:

preg_replace('/\n+|\t+|\s+/',' ',$string);

1

це замінить кілька вкладок однією вкладкою

preg_replace("/\s{2,}/", "\t", $string);

-2

Без preg_replace, за допомогою петлі.

<?php

$str = "This is   a Text \n and so on \t     Text text.";
$str_length = strlen($str);
$str_arr = str_split($str);
for ($i = 0; $i < $str_length; $i++) {
    if (isset($str_arr[$i + 1])
       && $str_arr[$i] == ' '
       && $str_arr[$i] == $str_arr[$i + 1]) {
       unset($str_arr[$i]);
    } 
    else {
      continue;
    }
}

 echo implode("", $str_arr) ; 

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