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?


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

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.


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.


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ą.


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;

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

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


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.


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.


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


-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);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.