Entfernen Sie mehrere Leerzeichen


208

Ich komme $row['message']aus einer MySQL-Datenbank und muss alle Leerzeichen wie \n \tund so weiter entfernen .

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

sollte formatiert werden für:

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

Ich habe es versucht:

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

aber es entfernt nicht \noder \tnur einzelne Leerzeichen. Kann mir jemand sagen, wie das geht?


1
Die Zeilenumbrüche und Tabulatoren stehen in einfachen Anführungszeichen. Sie möchten sie also wörtlich?
Mark Lalor

Ich habe das Zitat des Code-Abschnitts mit \ n und \ t korrigiert, indem ich es in doppelte Anführungszeichen geändert habe.
Buttle Butkus

Antworten:


394

Du brauchst:

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

Sie verwenden ein \s\s+Leerzeichen (Leerzeichen, Tabulator oder Zeilenumbruch), gefolgt von einem oder mehreren Leerzeichen. Dies bedeutet effektiv, dass zwei oder mehr Leerzeichen durch ein einzelnes Leerzeichen ersetzt werden.

Sie möchten ein oder mehrere Leerzeichen durch ein einzelnes Leerzeichen ersetzen, damit Sie das Muster \s\s*oder \s+(empfohlen) verwenden können.


1
Seine Methode ist besser als diese: Warum sollten Sie ein Leerzeichen durch ein Leerzeichen ersetzen?
Nickf

16
Er möchte auch, dass \ n und \ t durch Leerzeichen ersetzt werden. Jetzt stimmt sein Muster nicht mit diesen überein, sagen wir für $ x = "funktioniert \ nthis \ twork"; Das OP möchte, dass alle Leerzeichen durch ein einzelnes Leerzeichen ersetzt werden.
Codaddict

@codaddict, wie können wir \ n behalten und alle anderen mehrfachen Leerzeichen und Tabulatoren aus der Zeichenfolge entfernen? Bitte helfen Sie mir
Mansoorkhan Cherupuzha

Können Sie genauer sagen, warum "\ s +" empfohlen wird?
Isius

6
Beachten Sie, dass in PHP \s"vertikale Registerkarte" nicht enthalten chr(11). Um es auch einzuschließen, müssen Sie spacedie Zeichenklasse verwenden: [[:space:]]+ php.net/manual/en/regexp.reference.character-classes.php
Yaroslav

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

Dies gibt aus

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

3
Du bist ein wahrer Lebensretter. Ich wollte gerade herausspringen, wenn das Fenster darüber ist.
Bikey77


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

\s enthält bereits Tabulatoren und neue Zeilen, daher scheint dieser obige reguläre Ausdruck ausreichend zu sein.


2
Eckige Klammern werden hier nicht benötigt, da sie nur eines enthalten. Die /mhaben keine Auswirkung, da es keine ^oder $Anker gibt und die /ukeine Auswirkung haben, außer sie etwas zu verlangsamen und zu sterben, wenn die Eingabezeichenfolge nicht gültig ist UTF-8 (es hat keinen Einfluss darauf, welche \sÜbereinstimmungen, aber es würde Auswirkungen haben \pZ).
Thomasrutter

12

vereinfacht zu einer Funktion:

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

basierend auf der Antwort von Danuel O'Neal.


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

2
Dies ist derjenige, der für mich am besten funktioniert hat. Außerdem würde ich Trim hinzufügen, um Leerzeichen am Anfang und Ende des Strings zu löschen
Dziamid

@ Dziamid Sie können es mit trim tun (preg_replace (...))
Balázs Varga

7

Ich kann das Problem hier nicht wiederholen:

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

Ich bin nicht sicher, ob es nur ein Transkriptionsfehler war oder nicht, aber in Ihrem Beispiel verwenden Sie eine Zeichenfolge in einfachen Anführungszeichen. \nund \twerden nur dann als neue Zeile und Tabulator behandelt, wenn Sie eine Zeichenfolge in doppelten Anführungszeichen haben. Das ist:

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

Bearbeiten : Wie Codaddict hervorhob, \s\s+wird kein einzelnes Tabulatorzeichen ersetzt. Ich denke immer noch nicht, dass die Verwendung \s+eine effiziente Lösung ist. Wie wäre es stattdessen damit:

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

2
+1, stimmt. Für eine Zeichenfolge mit vielen einzelnen Leerzeichen (was normalerweise der Fall ist) ist es ineffizient, ein Leerzeichen durch Leerzeichen zu ersetzen.
Codaddict

1
@coaddict: Um Ihre Hypothese zu testen, habe ich ein schnelles Skript geschrieben, um 1000 von jedem Ersatz durchzugehen und das Timing von jedem zu überprüfen. Für die Zeichenfolge '+1, True. Für eine Zeichenfolge mit vielen einzelnen Leerzeichen (was normalerweise der Fall ist) ist es ineffizient, ein Leerzeichen durch Leerzeichen zu ersetzen. - codaddict 24. Februar \ '10 um 13:32 ' , eintausend \ s + preg_replace () -Anrufe dauerten 0,010547876358032 Sekunden, und eintausend (?: \ S \ s + | \ n | \ t) preg_replace () -Anrufe dauerten 0,013049125671387 es ist fast 30% langsamer.
Joseph Cheek

Vielleicht möchten Sie diesem letzten Beispiel "\ r" hinzufügen, da einige Computer ein einzelnes "\ r" alleine verwenden (Apple Mac?)
thomasrutter

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

Dies ersetzt alle Tabulatoren, alle Zeilenumbrüche und alle Kombinationen aus mehreren Leerzeichen, Registerkarten und Zeilenumbrüchen durch ein einziges Leerzeichen.


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

statische Funktion remove_whitespace ist aus welchem ​​Grund? Sie definieren es, verwenden es aber nie.
Lukas Liesis

Diese haben jeweils ihre Verwendung, aber keine davon würde das erreichen, was die Frage verlangt, nämlich mehrere aufeinanderfolgende Leerzeichen durch nur ein Leerzeichen zu ersetzen. Ihr "remove_doublewhitespace" würde nur mehrere gleiche Whitespace-Zeichen ersetzen, also würde er "\ n \ n \ n" durch ein '' ersetzen, aber es würde nichts gegen "\ r \ n"
tun

4

Ohne 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

Ich benutze diesen Code und dieses Muster:

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;

Sie können dies unter http://writecodeonline.com/php/ testen.


Es funktioniert mit mir sogar in mariaDB in dieser Abfrage: SELECT search_able, REGEXP_REPLACE (search_able,"\\s+",' ') FROM book where id =260 Also vielen Dank
Jalmatari

1

Alles was Sie brauchen, ist es wie folgt auszuführen:

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

Dies ist, was ich verwenden würde:

ein. Stellen Sie sicher, dass Sie doppelte Anführungszeichen verwenden, zum Beispiel:

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

b. Verwenden Sie zum Entfernen zusätzlicher Leerzeichen:

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

Es ist vielleicht nicht die schnellste Lösung, aber ich denke, es wird den geringsten Code erfordern, und es sollte funktionieren. Ich habe jedoch noch nie MySQL verwendet, daher kann ich mich irren.


1

In Wahrheit, wenn Sie denken, dass Sie so etwas wollen:

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

1

Dadurch werden mehrere Registerkarten durch eine einzelne Registerkarte ersetzt

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

-2

Ohne preg_replace mit Hilfe der Schleife.

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

 ?>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.