2016-11-16 2 views
10

Я пытаюсь ввести split строку в ее символы компонента.
Для этой цели я всегда использовал split(//, $str) как это было предложено the documentation:

Однако это:
print join(':', split(//, 'abc')), "\n";
использует пустая строка соответствует в качестве разделителей для получения выходного сигнала a:b:c; таким образом, пустую строку можно использовать для разделения EXPR на список его компонентных символов.

В моем сценарии я нужен массив из первых N символов или первые length($str) - 1 символов, в зависимости от того, что меньше. Для этого я использую split(//, $str, $n + 1) и отбрасываю последний элемент.

В теории это должно сработать. Если LIMIT меньше длины строки, все дополнительные символы сгруппированы в последний элемент, который отбрасывается. Если LIMIT больше длины строки, последний элемент - последний символ, который отбрасывается.

Здесь я столкнулся с проблемой.

В документации сказано:

... и каждый из них:
print join(':', split(//, 'abc', 3)), "\n";
print join(':', split(//, 'abc', 4)), "\n";
производит выход a:b:c.

Но это не результат, который я получаю. Если LIMIT больше, чем количество символов, результирующий массив всегда заканчивается точно один пустой элемент (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: 

Эти результаты непосредственно противоречат пример из документации.

Неправильная ли документация? Неверна ли моя версия Perl (v5.22.2)?
Если этого нельзя избежать, как я могу выполнить свою первоначальную цель?

+0

Вы можете в конечном итоге изменить свой пустой шаблон на '/ (?! $) /'. –

+1

Ну, альтернативный способ может быть разделен (//, substr ($ string, 0, $ n)) ' – infixed

+2

Я думаю, что документ просто неверен. Если предел больше длины, следует включить пустую строку после совпадения нулевой ширины в конце. – ysth

ответ

7

Похоже, что пример в документации неверен. Чуть дальше вниз по документации является следующее:

пустого поля ведомой, с другой стороны, производится, когда есть совпадение в конце EXPR, независимо от продолжительности матча (конечно, если явно задано ненулевое значение LIMIT, такие поля удаляются, как в последнем примере).

Поскольку я предоставляю ненулевой LIMIT, сохраняются пустые поля. Пустой шаблон // соответствует последнему символу, но до конца строки, так что получается ровно одно конечное пустое поле.

В обходных предложенном в комментарии – с использованием разделенного шаблона из (?!$) или с использованием substr($str, 0, $n) в качестве входного сигнала – и работу.
Однако вместо того, чтобы принуждать split к сотрудничеству, я решил обновить логику «отбросить последний элемент» от pop(@arr) до while (@arr && pop(@arr) eq "") { }.

Смежные вопросы