2016-11-16 14 views
10

Próbuję wprowadzić split ciąg znaków w jego składowych.
W tym celu zawsze stosować split(//, $str) jak sugeruje the documentation:

Jednak to:
print join(':', split(//, 'abc')), "\n";
wykorzystuje pusty string pasuje jako separatory do produkują wyjście a:b:c; w ten sposób pusty ciąg może być użyty do podzielenia WYRAŻA na listę jego znaków składowych.

W moim scenariuszu muszę tablicę z pierwszych N znaków lub pierwsze length($str) - 1 znaków, przy czym chodzi mniej. Aby to osiągnąć, używam split(//, $str, $n + 1) i odrzucam ostatni element.

Teoretycznie powinno to zadziałać. Jeśli LIMIT jest mniejsza niż długość łańcucha, wszystkie dodatkowe znaki są pogrupowane w ostatni element, który jest odrzucany. Jeśli LIMIT jest większy niż długość łańcucha, ostatnim elementem jest ostatni znak, który jest odrzucany.

To tutaj napotykam na mały problem.

Dokumentacja mówi:

... i każdy z nich:
print join(':', split(//, 'abc', 3)), "\n";
print join(':', split(//, 'abc', 4)), "\n";
produkuje wyjście a:b:c.

Ale to nie jest skutek, który otrzymuję. Jeśli LIMIT jest większa od liczby znaków, uzyskany tablica zawsze kończy dokładnie jeden element pusty (demo):

print join(':', split(//, 'abc', 1)), "\n"; # abc 
print join(':', split(//, 'abc', 2)), "\n"; # a:bc 
print join(':', split(//, 'abc', 3)), "\n"; # a:b:c 
print join(':', split(//, 'abc', 4)), "\n"; # a:b:c: 
print join(':', split(//, 'abc', 99)), "\n"; # a:b:c: 

Wyniki te bezpośrednio sprzeczne przykład z dokumentacji.

Czy dokumentacja jest nieprawidłowa? Czy moja wersja Perla (wer.2.2.2) jest błędna?
Jeśli tego zachowania nie da się uniknąć, w jaki sposób mogę osiągnąć mój pierwotny cel?

+0

Możesz ostatecznie zmienić pusty wzór na '/ (?! $) /'. –

+1

Cóż, alternatywnym sposobem może być 'split (//, substr ($ string, 0, $ n))' – infixed

+2

Myślę, że dokument jest po prostu błędny. Jeśli limit jest dłuższy niż długość, należy uwzględnić pusty ciąg po dopasowaniu szerokości zera na końcu. – ysth

Odpowiedz

7

Wygląda na to, że przykład w dokumentacji jest nieprawidłowy. Nieco dalej w dół dokumentacji jest następujący:

pustym polu wleczonego, z drugiej strony, jest produkowany, gdy nie jest mecz na koniec WYRAŻ, niezależnie od długości meczu (oczywiście, jeśli nie podano LIMITU niezerowego, takie pola są usuwane, jak w ostatnim przykładzie).

Ponieważ dostarczam LIMIT niezerowy, końcowe puste pola są zachowywane. Pusty wzorzec // dopasowuje się po ostatnim znaku, ale przed końcem łańcucha, tak więc powstaje dokładnie jedno końcowe puste pole.

Obejścia proponowane w komentarzach – przy użyciu wzoru podziału (?!$) lub przy użyciu substr($str, 0, $n) jako danych wejściowych – obie prace.
Jednak zamiast zmuszać do współpracy split, zdecydowałem się zaktualizować logikę "wyrzucić ostatni element" z pop(@arr) do while (@arr && pop(@arr) eq "") { }.

Powiązane problemy