Jak mogę rozbić i przyciąć białe znaki?

167

Na przykład chciałbym utworzyć tablicę z elementów w tym ciągu:

$str = 'red,     green,     blue ,orange';

Wiem, że możesz eksplodować, przechodzić przez nie w pętlę i przycinać:

$arr = explode(',', $str);
foreach ($arr as $value) {
    $new_arr[] = trim($value);
}

Ale czuję, że istnieje podejście jednokierunkowe, które może sobie z tym poradzić. Jakieś pomysły?

SeanWM
źródło

Odpowiedzi:

449

Możesz wykonać następujące czynności za pomocą array_map :

$new_arr = array_map('trim', explode(',', $str));
SeanWM
źródło
10
To również jest zapętlone (wewnętrznie) przez PHP
Jason OOO
2
to .... uratowało ... moje ... życie .... Próbowałem manipulować plikiem przez fseek, aby dołączyć go na końcu pliku ... kiedy zdecydowałem się podzielić go na tablicę i przepisać plik, widziałem, że przez cały czas były dodawane dodatkowe białe spacje ... ta + imploda uratowała moje cholerne życie .. Mogę teraz iść jeść.
jenki221
4
@JasonOOO Myślę, że w opinii większości ludzi kilka milisekund (jeśli nawet to) to uczciwy kompromis za posiadanie linii kodu, która jest krótka, prosta i czytelna.
Gavin,
Proste i łatwe do zrozumienia. Jeśli jednak mamy do czynienia z dużymi zbiorami danych, wydajniejsza odpowiedź udzielona przez @ amr-eladwy jest lepszym rozwiązaniem.
Yaron
Uwielbiam ten fragment kodu i od czasu do czasu wracam na tę stronę!
patrickzzz
52

Ulepszona odpowiedź

preg_split ('/(\s*,*\s*)*,+(\s*,*\s*)*/', 'red,     green thing ,,  ,,   blue ,orange');

Wynik:

Array
(
    [0] => red
    [1] => green thing
    [2] => blue
    [3] => orange
)

To

  • Dzieli tylko przecinkami
  • Przycina białe przestrzenie z każdego elementu.
  • Ignoruje puste elementy
  • Nie dzieli elementu wewnętrznymi spacjami, takimi jak „zielona rzecz”
Amr ElAdawy
źródło
7
Czy ktoś może mi wyjaśnić, dlaczego ta odpowiedź nie ma 100 głosów za? Regexp jest trudny do zrozumienia, ale przeanalizował mój plik 100 MB szybciej niż inne rozwiązania
Dan
2
Cieszę się, że okazało się to pomocne. Przeczytałem wszystkie odpowiedzi i wyszedłem z lepszą mieszanką. Wyrażenie regularne można szczegółowo wyjaśnić.
Amr ElAdawy
2
Przepraszamy, ale to regex jest źle - spróbuj wymienić redz *red*. Lepszym może być / (\ s *, \ s *) + /
Greg,
@AmrElAdawy FYI to już nie działa po aktualizacji 8/28. Gdy wyrażenie regularne w odpowiedzi jest takie, jakie jest, białe znaki nie są usuwane z niektórych elementów. Np .: „zielona rzecz”.
Samsquanch
1
Zaktualizowano @Samsquanch. Daj mi znać, jeśli zauważysz jakiś problem.
Amr ElAdawy
25

Poniższy przykład zajmuje się również spacjami na początku / końcu ciągu wejściowego:

$new_arr = preg_split('/\s*,\s*/', trim($str));

a to jest minimalny test ze spacjami w każdej rozsądnej pozycji:

$str = ' first , second , third , fourth, fifth ';
$new_arr = preg_split('/\s*,\s*/', trim($str));
var_export($str);
Diego Perini
źródło
Ponieważ array_maprozwiązania regexp dają identyczne wyniki, czy ktoś mógłby porównać ich wydajność?
Dan
@Dan W takich przypadkach nie będzie żadnej różnicy.
Aris,
4

w ten sposób zastępujesz i eksplodujesz w pojedynczym wierszu kodu

$str = 'red,     green,     blue ,orange';

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

wyświetli wyniki jako

Array
(
    [0] => red
    [1] => green
    [2] => blue
    [3] => orange
)
Amit Sharma
źródło
3

Łącząc niektóre z głównych zasad w istniejących odpowiedziach, które wymyśliłem

preg_split ('/\s*,+\s*/', 'red,     green thing ,,  ,,   blue ,orange', NULL, PREG_SPLIT_NO_EMPTY);

Powodem tego jest to, że znalazłem błąd w tej odpowiedzi , gdzie jeśli na końcu ciągu znajduje się przecinek, zwróci on pusty element w tablicy. to znaczy

preg_split ('/(\s*,*\s*)*,+(\s*,*\s*)*/', 'red,     green thing ,,  ,,   blue ,orange,');

Prowadzi do

Array
(
  [0] => red
  [1] => green thing
  [2] => blue
  [3] => orange
  [4] => ''
)

Możesz to naprawić, używając PREG_SPLIT_NO_EMPTY, jak wspomniano w tej odpowiedzi, aby go usunąć, ale gdy to zrobisz, technicznie nie ma potrzeby usuwania kolejnych przecinków za pośrednictwem wyrażenia regularnego, stąd skrócone wyrażenie

shmurf
źródło
2

Możesz to również zrobić za pomocą wyrażenia regularnego z jedną linią

preg_split('@(?:\s*,\s*|^\s*|\s*$)@', $str, NULL, PREG_SPLIT_NO_EMPTY);
Dom
źródło
1

Spróbuj tego:

$str = preg_replace("/\s*,\s*/", ",", 'red,     green,     blue ,orange');
Jason OOO
źródło
OP chce macierzy. preg_replace()nie generuje tablicy z łańcucha. To jest właściwa odpowiedź na złe pytanie. Głosowano w dół.
mickmackusa
1
$list = preg_split("/\s*,\s*/", 'red, green, blue ,orange');drobna modyfikacja rehabilituje odpowiedź
dreftymac
1

SZCZEGÓLNIE dla przykładowego ciągu OP, ponieważ każdy dopasowywany podciąg to pojedyncze słowo, możesz użyć str_word_count () .

Kod: ( Demo )

$str = ' red,     green,     blue ,orange ';
var_export(str_word_count($str,1));  // 1 means return all words in an indexed array

Wynik:

array (
  0 => 'red',
  1 => 'green',
  2 => 'blue',
  3 => 'orange',
)

Można to również dostosować do podciągów poza literami (i niektórych myślników i apostrofów - jeśli czytasz drobny druk), dodając niezbędne znaki do maski znaku / trzeciego parametru.

Kod: ( Demo )

$str = " , Number1 ,     234,     0 ,4heaven's-sake  ,  ";
var_export(str_word_count($str,1,'0..9'));

Wynik:

array (
  0 => 'Number1',
  1 => '234',
  2 => '0',
  3 => '4heaven\'s-sake',
)

Ponownie traktuję to pytanie bardzo wąsko ze względu na przykładowy ciąg, ale zapewni to ten sam pożądany wynik:

Kod: ( Demo )

$str = ' red,     green,     blue ,orange ';
var_export(preg_match_all('/[^, ]+/',$str,$out)?$out[0]:'fail');
mickmackusa
źródło
0

Możesz do tego użyć preg_split () .

$bar = preg_split ('/[,\s]+/', $str);
print_r ($bar);

/* Result:
  Array
  (
      [0] => red
      [1] => green
      [2] => blue
      [3] => orange
  )
 */
Sutandiono
źródło
To rozdzieli się na przestrzenie w twoich żywiołach
Chris KL
Przesuń przecinek na lewo od nawiasów kwadratowych, aby był wymagany.
Eric Leschinski
Przeniesienie przecinka w lewo tego nie rozwiąże. Proszę sprawdzić moją odpowiedź poniżej stackoverflow.com/a/38300330/5079380
Amr ElAdawy
-4
$str = str_replace(" ","", $str);
Czarny biały
źródło
4
Trim robi więcej niż to ... Przycina \t\n\r\0\x0Brównież
Arian Faurtosh
3
Nie tylko to, ale to zepsuje przestrzeń.
Adam Kiss
-11

przyciąć i eksplodować

$ str = 'czerwony, zielony, niebieski, pomarańczowy';

$ str = przycinanie ($ str);

$ strArray = eksplodować (',', $ str);

print_r ($ strArray);

Anil M Saini
źródło
5
Spowoduje to tylko usunięcie białych znaków z początku i końca ciągu, a nie między poszczególnymi kolorami.
SeanWM