Использование split (//, $str, $limit), возвращающее конечные пустые элементы, что противоречит документации
Я пытаюсь выполнить split
строку в ее символах компонента.
Для этой цели я всегда использовал split(//, $str)
, как было предложено документация:
Однако, это:
print join(':', split(//, 'abc')), "\n";
использует пустые строки в качестве разделителей для вывода вывода a:b:c
; таким образом, пустую строку можно использовать для разделения EXPR на список его компонентных символов.
В моем script мне нужен массив из первых 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) неправильной?
Если этого нельзя избежать, как я могу выполнить свою первоначальную цель?
Ответы
Ответ 1
Похоже, что пример в документации неверен. Ниже приведена следующая документация:
Пустое конечное поле, с другой стороны, создается, когда есть совпадение в конце EXPR, независимо от длины совпадения (конечно, если явно задано ненулевое значение LIMIT, такие поля удаляются, как в последнем примере).
Поскольку я предоставляю ненулевой LIMIT, сохраняются пустые поля. Пустой шаблон //
совпадает с окончательным символом, но до конца строки, поэтому создается ровно одно конечное пустое поле.
Обходные пути, предложенные в комментариях; используя шаблон разделения (?!$)
или используя substr($str, 0, $n)
в качестве входного сигнала; оба работают.
Однако вместо принудительного взаимодействия split
я решил обновить логику "отбросить конечный элемент" от pop(@arr)
до while (@arr && pop(@arr) eq "") { }
.