Usuń nadmiar białych znaków z ciągu

138

Otrzymuję ciąg z zapytania do bazy danych, a następnie usuwam wszystkie znaczniki HTML, powroty karetki i znaki nowej linii, zanim umieszczę je w pliku CSV. Chodzi tylko o to, że nie mogę znaleźć sposobu na usunięcie nadmiaru białych znaków spomiędzy ciągów.

Jaki byłby najlepszy sposób na usunięcie wewnętrznych białych znaków?

joepour
źródło
6
Prosimy o przesłanie próbki oryginalnego i poszukiwanego ciągu.
Zote
Czy możesz również wyjaśnić, jaki powinien być końcowy efekt? Czy wstawiasz przecinki do danych dla CSV, pobierasz je z bazy danych z już przecinkami, wprowadzasz ciągi znaków do funkcji, która obsługuje wstawianie CSV itp.?
Frank DeRosa
ok, końcowe wyjście musi być łańcuchem z każdym słowem oddzielonym pojedynczą spacją, w tej chwili jest to wiele białych znaków.
joepour
1
@Joe, nie marnowałbym czasu i zacząłbym doceniać wszystkich, którzy wcześniej ci pomogli! :)
Frankie

Odpowiedzi:

293

Nie wiesz dokładnie, czego chcesz, ale oto dwie sytuacje:

  1. Jeśli jesteś po prostu do czynienia z nadmiarem whitespacena początku lub na końcu łańcucha można użyć trim(), ltrim()lub rtrim()go usunąć.

  2. Jeśli masz do czynienia z dodatkowymi spacjami w ciągu, rozważ preg_replacewielokrotność whitespaces " "*z pojedynczą whitespace " ".

Przykład:

$foo = preg_replace('/\s+/', ' ', $foo);
jW.
źródło
62
$ foo = preg_replace ('/ \ s + /', '', $ foo);
genio
użycie $foo = preg_replace( '/\s+/', ' ', $foo );zabije efektynl2br()
Waiyl Karim
1
po prostu użyj nl2br przed użyciem preg_replace i powinieneś być gotowy.
Lukas Liesis,
Literówka / Escaper uwaga - jeśli kod nie usuwa dodatkowych białych znaków - upewnij się, że masz „\” przed „s” :) niektóre strony testujące php online usuwają go :)
jave.web
To powinno być bezpieczne dla CSS, prawda? Jak w przypadku, to bezpiecznie skompresowałoby zmienną zawierającą długi, wieloliniowy ciąg CSS?
David
51
$str = str_replace(' ','',$str);

Lub zastąp podkreśleniem & nbsp; itd itd.

Cory Dee
źródło
8
Spowoduje to usunięcie wszystkich białych znaków. Chce tylko znormalizować strunę.
Svend
13
To, czego szukałem (chociaż nie było to pytanie)
Robert Johnstone
@Gigala "Jaki byłby najlepszy sposób na usunięcie wewnętrznych białych znaków?" było pytanie. Ta odpowiedź doskonale to spełnia.
Cory Dee
1
@CoryDee To prawda, w tym ostatnim zdaniu. Ale we wstępie pytanie jest sformułowane jako „ nadmiar białych znaków”, z naciskiem na nadmiar. Skończyło się na tym, że spełniłeś RZECZYWISTY problem OP, więc nie ma to większego znaczenia, ale o ile zajmiemy się tym technicznie ...
Spencer Ruskin
To nie działa, jeśli liczyć od przestrzeni jest liczba nawet , powiedzmy: Hi Earthz 4 przestrzenie pomiędzy nimi będzie: HiEarth. To nie rozwiązuje mojego problemu związanego z pytaniem.
JJ Labajo
26

$str = trim(preg_replace('/\s+/',' ', $str));

Powyższy wiersz kodu usunie dodatkowe spacje, a także spacje wiodące i końcowe.

d -_- b
źródło
25

żaden z innych przykładów nie działał dla mnie, więc użyłem tego:

trim(preg_replace('/[\t\n\r\s]+/', ' ', $text_to_clean_up))

spowoduje to zastąpienie wszystkich tabulatorów, nowych linii, podwójnych spacji itp. prostą 1 spacją.

Lukas Liesis
źródło
Dzięki @ wp78de, ale z jakiegokolwiek powodu miałem problemy z tylko \s+. Chociaż było to w 2014 roku, więc może zostało zmienione, nie dotykałem PHP przez ostatnie 3 lata, nie mogę komentować, ale pozostawi aktualną odpowiedź, gdy było to rozwiązanie i może nadal być w niektórych przypadkach.
Lukas Liesis,
9

Jeśli chcesz zamienić tylko wiele spacji w ciągu, na przykład: "this string have lots of space . " I oczekujesz odpowiedzi "this string have lots of space", możesz użyć następującego rozwiązania:

$strng = "this string                        have lots of                        space  .   ";

$strng = trim(preg_replace('/\s+/',' ', $strng));

echo $strng;
Apsar
źródło
5

Istnieją luki bezpieczeństwa w używaniu preg_replace (), jeśli otrzymujesz ładunek z danych wejściowych użytkownika [lub innych niezaufanych źródeł]. PHP wykonuje wyrażenie regularne za pomocą eval (). Jeśli przychodzący ciąg nie jest prawidłowo oczyszczony, aplikacja może zostać poddana wstrzyknięciu kodu .

W mojej własnej aplikacji, zamiast zawracać sobie głowę oczyszczaniem danych wejściowych (i ponieważ mam do czynienia tylko z krótkimi ciągami znaków), zamiast tego utworzyłem nieco bardziej intensywną funkcję procesora, która jest jednak bezpieczna, ponieważ niczego nie eval ().

function secureRip(string $str): string { /* Rips all whitespace securely. */
  $arr = str_split($str, 1);
  $retStr = '';
  foreach ($arr as $char) {
    $retStr .= trim($char);
  }
  return $retStr;
}
Fom
źródło
Wykonuje go przy użyciu eval tylko wtedy, gdy podasz modyfikator „e”: php.net/manual/en/… zawiera również informację, że „Ta funkcja została WYCOFANA w PHP 5.5.0 i USUNIĘTA od PHP 7.0.0. " Więc nie możesz już oceniać rzeczy w preg_replace.
ADJenks
4
$str = preg_replace('/[\s]+/', ' ', $str);
Sandip Layek
źródło
2

Możesz użyć:

$str = trim(str_replace("  ", " ", $str));

To usuwa dodatkowe spacje z obu stron ciągu i konwertuje dwie spacje na jedną w ciągu. Zwróć uwagę, że nie spowoduje to konwersji trzech lub więcej spacji z rzędu na jedną! Innym sposobem, który mogę zasugerować, jest użycie implodowania i eksplozji, które jest bezpieczniejsze, ale całkowicie nieoptymalne!

$str = implode(" ", array_filter(explode(" ", $str)));

Moją sugestią jest użycie natywnej pętli for lub użycie regex do tego rodzaju pracy.

Amir Fo
źródło
Nie powoduje to poprawnej konwersji wielu spacji, gdy przestrzeń jest dłuższa niż dwie spacje.
mikeybeck
1

Aby rozwinąć odpowiedź Sandipa, w dziennikach pojawiło się kilka ciągów znaków, które zostały błędnie zakodowane w bit.ly. Chcieli zakodować tylko adres URL, ale po spacji umieścili uchwyt twittera i kilka innych rzeczy. Wyglądało to tak

? productID =26%20via%20@LFS

Zwykle nie stanowi to problemu, ale otrzymuję wiele prób iniekcji SQL, więc przekierowuję wszystko, co nie jest prawidłowym identyfikatorem, na 404. Użyłem metody preg_replace, aby przekształcić nieprawidłowy ciąg productID w ciąg prawidłowy identyfikator produktu.

$productID=preg_replace('/[\s]+.*/','',$productID);

Szukam spacji w adresie URL, a następnie usuwam wszystko po nim.

JScarry
źródło
0

Niedawno napisałem prostą funkcję, która usuwa nadmiar białych znaków z łańcucha bez wyrażeń regularnych implode(' ', array_filter(explode(' ', $str))).

Zsolt Oroszlány
źródło
-1
$str = "I      am a PHP   Developer";
$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