Usuń wiele białych znaków

208

Dostaję $row['message']z bazy danych MySQL i muszę usunąć wszystkie białe znaki jak \n \ti tak dalej.

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

powinien być sformatowany do:

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

Próbowałem:

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

ale nie usuwa \nani \ttylko pojedynczych spacji. Czy ktoś może mi powiedzieć, jak to zrobić?

creativz
źródło
1
Znaki nowej linii i tabulatory są w pojedynczych cudzysłowach, więc chcesz, żeby były dosłowne?
Mark Lalor,
Poprawiłem cytowanie fragmentu kodu za pomocą \ n i \ t, zmieniając go na podwójne cudzysłowy.
Buttle Butkus,

Odpowiedzi:

394

Potrzebujesz:

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

Używasz \s\s+co oznacza białe spacje (spację, tabulator lub znak nowej linii), po których następuje jedna lub więcej białych spacji. Co skutecznie oznacza zastąpienie dwóch lub więcej białych znaków pojedynczą spacją.

To, czego chcesz, to zastąpić jedną lub więcej białych spacji pojedynczą białą spacją, abyś mógł użyć wzoru \s\s*lub \s+(zalecane)

kodaddict
źródło
1
jego metoda jest lepsza: dlaczego zastąpić jedną spację jedną spacją?
nickf
16
Chce też \ n i \ t zostać zastąpione spacją. Teraz jego wzorzec nie pasuje do tych, powiedzmy dla $ x = "robi \ nthis \ twork"; OP chce, aby wszystkie białe znaki zostały zastąpione jedną spacją.
codaddict
@codaddict, jak możemy zachować \ n i usunąć wszystkie inne wielokrotne spacje i tabulatory z ciągu? pomóżcie mi
Mansoorkhan Cherupuzha,
Czy możesz sprecyzować, dlaczego „\ s +” jest zalecane?
Isius
6
Zauważ, że w PHP \snie ma „pionowej zakładki” chr(11). Aby go również dołączyć, musisz użyć spaceklasy postaci: [[:space:]]+ php.net/manual/en/regexp.reference.character-classes.php
Jarosław
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";
?>

To wychodzi

This is  a string   with
spaces, tabs and newlines present
---
This is a string with spaces, tabs and newlines present
Cez
źródło
3
Jesteś prawdziwym ratownikiem. Już miałam wyskoczyć, jeśli przez to okno.
bikey77
Zgrabne, wciąż pomocne
spekulatius
16
preg_replace('/[\s]+/mu', ' ', $var);

\s zawiera już tabulatory i nowe wiersze, więc powyższe wyrażenie regularne wydaje się wystarczające.

Anonimowy
źródło
2
Nawiasy kwadratowe nie są tutaj potrzebne, ponieważ jest w nich tylko jedna rzecz. Nie przyniesie /mefektu, ponieważ nie ma żadnych ^lub $zakotwiczeń, a /unie przyniesie żadnego efektu poza nieznacznym spowolnieniem i zgonem, jeśli łańcuch wejściowy nie jest prawidłowy UTF-8 (nie wpływa na to \s, które dopasowania, ale wpłynie na \pZ).
thomasrutter
12

uproszczony do jednej funkcji:

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

na podstawie odpowiedzi Danuela O'Neala.

Lukas Liesis
źródło
7
$str='This is   a Text \n and so on Text text.';
print preg_replace("/[[:blank:]]+/"," ",$str);
ghostdog74
źródło
2
Ten był dla mnie najlepszy. Dodałbym też wykończenie, aby usunąć białe znaki na początku i na końcu łańcucha
Dziamid
@Dziamid Możesz to zrobić za pomocą przycinania (preg_replace (...))
Balázs Varga
7

Nie mogę odtworzyć problemu tutaj:

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

Nie jestem pewien, czy był to tylko błąd transkrypcji, czy nie, ale w twoim przykładzie używasz ciągu pojedynczego cudzysłowu. \ni \tsą traktowane jako nowa linia i tabulator tylko wtedy, gdy masz ciąg cudzysłowu. To jest:

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

Edycja : jak wskazał Codaddict, \s\s+nie zastąpi znaku pojedynczej karty. Nadal nie sądzę, aby używanie \s+było wydajnym rozwiązaniem, więc co powiesz na to:

preg_replace('/(?:\s\s+|\n|\t)/', ' ', $x);
pseudonim
źródło
2
+1, prawda. W przypadku łańcucha z dużą ilością pojedynczych spacji (co zwykle ma miejsce) nieskuteczne jest zastępowanie spacji spacją.
codaddict
1
@coaddict: aby przetestować twoją hipotezę, napisałem szybki skrypt, aby przejrzeć 1000 każdej wymiany i sprawdzić czas każdej z nich. Dla ciągu „+1, prawda. W przypadku łańcucha z dużą ilością pojedynczych spacji (co zwykle ma miejsce) nieskuteczne jest zastępowanie spacji spacją. - codaddict 24 lutego '10 o 13:32 ' , tysiąc wywołań + preg_replace () zajęło 0,010547876358032 sekund, a tysiąc (?: \ S \ s + | \ n | \ t ) wywołań preg_replace () zajęło 0,013049125671387, dzięki czemu prawie 30% wolniej.
Joseph Cheek
Możesz dodać „\ r” do tego ostatniego przykładu, ponieważ niektóre komputery używają pojedynczego „\ r” na swoim (Apple Mac?)
thomasrutter
4
preg_replace('/(\s\s+|\t|\n)/', ' ', $row['message']);

Zastępuje to wszystkie tabulatory, wszystkie znaki nowej linii i wszystkie kombinacje wielu spacji, tabulatorów i znaków nowej linii pojedynczą spacją.

środkowy
źródło
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);
Danuel O'Neal
źródło
z jakiego powodu jest funkcja statyczna remove_whitespace? Definiujesz, ale nigdy go nie używasz.
Lukas Liesis
Każdy z nich ma swoje zastosowanie, ale żaden z nich nie osiągnąłby tego, o co pyta pytanie, a mianowicie zastąpienia wielu kolejnych białych znaków tylko jednym. Twoja „remove_doublewhitespace” zastąpiłaby tylko wielokrotność tego samego znaku białych znaków, więc zastąpiłaby „\ n \ n \ n” znakiem „”, ale nie zrobiłaby nic z „\ r \ n”
thomasrutter
4

Bez 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;
hharek
źródło
2

Używam tego kodu i wzoru:

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;

Możesz to przetestować na http://writecodeonline.com/php/

Catalin T.
źródło
Działa ze mną nawet w mariaDB w tym zapytaniu: SELECT search_able, REGEXP_REPLACE (search_able,"\\s+",' ') FROM book where id =260 Więc wielkie dzięki
jalmatari
1

Wystarczy uruchomić go w następujący sposób:

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.
Alex Polo
źródło
1

Chciałbym użyć tego:

za. Pamiętaj, aby używać podwójnych cudzysłowów, na przykład:

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

b. Aby usunąć dodatkowe białe znaki, użyj:

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

To może nie być najszybsze rozwiązanie, ale myślę, że będzie wymagało najmniejszego kodu i powinno działać. Jednak nigdy nie korzystałem z mysql, więc mogę się mylić.

matsolof
źródło
1

Prawdę mówiąc, jeśli uważasz, że chcesz czegoś takiego:

preg_replace('/\n+|\t+|\s+/',' ',$string);
BigBlast
źródło
1

spowoduje to zastąpienie wielu kart jedną kartą

preg_replace("/\s{2,}/", "\t", $string);
Heman G.
źródło
-2

Bez preg_replace, za pomocą pętli.

<?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) ; 

 ?>
Shahbaz Khan
źródło