Страница 1 из 1

Обрезание строк

Добавлено: 09 июн 2005, 18:15
Natashka
Подскажите пожалуйста, как обрезать строку с использованием оператора printf.

Дело обстоит так:

Код: Выделить всё

sub new_header {
	$header{"_Printed"} = 0;
	$header{"_Format"} = "%04d%04d%04d%02d%-12s%-10s%1s\n";
	$header{"_Fields"} = ["_Fahrt", "_SDG", "_BZ", "_SA", "TF_ERSTDAT", "ADR_ADRID", "TF_FLAG"];
	$header{"_Fahrt"} = 0;
	$header{"_SDG"} = 0;
	$header{"_BZ"} = 0;
	$header{"_SA"} = 1;
	$header{"TF_ERSTDAT"} = "";
	$header{"ADR_ADRID"} = "";
	$header{"TF_FLAG"} = "";
}
И нужно сделать так, чтобы при вызове функции: printf ($header{"_Format"}, @header{@$fields});
записывалось только то количество символов, которое указано в формате.

Может, есть какой-то особенный спецификатор?

Просто вариант: $header{"TF_ERSTDAT"} = substr $header{"TF_ERSTDAT"}, 0, 12; в принципе не устраивает, потому что таких переменных до ужаса много...

Есть еще, на сколько я знаю, способ записи через FORMAT, но им пользоваться до сих пор не приходилось.

Подскажите, как лучше всего справиться с поставленной задачей.

Заранее благодарна.

Добавлено: 10 июн 2005, 03:11
Oscar
Natashka,

Вижу, что это НЕ php. Наверное таки perl? На asp, вроди как, не похоже.
Суть поставленной задачи так и не понял.

Но если это поможет - тут можно почитать про параметры printf.

А если при помощи printf не получится, то для резания (и не только) строк - есть такая мощная структура, как Регулярные выражения.

Даже если это и НЕ PHP - всё равно советую почитать документацию, что я дал.
Ведь в конечном итоге всё равно всё на Си делается ;-)

К тому же в "regExp"-ах там указаны отличия PHP от Perl.
Кроме того, поскольку Perl изначально был текстово-ориентирован - в Инете полно всякого добра про построение регулярных выражений для него.

Если вдруг всё, что я написал - бред и не поможет, - заранее прошу прощения.

Добавлено: 10 июн 2005, 12:17
Natashka
Да, конечно, поторопилась, и недостаточно подробно написала.

Пишу на Перле, разбираю XML-файл, сохраняю его в хитрую форму. И, в частности, столкнулась с такой проблемой, что для каждого значения строго определена максимальная длина. Поэтому слишком длинные строки придется обрезать.

Но так как я с этим языком столкнулась относительно недавно, а задание сделать надо к установленному сроку, приходится выкручиваться любыми способами. Правда, есть желание выбрать сразу лучший, чтобы потом не переделывать ;)

В идеале хотелось бы получить что-нибудь в духе:
$header{"_Format"} = "%~04d%~04d%~04d%~02d%~-12s%~-10s%~1s\n";
где тильда - чудесный значок, который показывает, что распечатается не более указанного количества символов.

Пока я этот мифический знак не нашла. Придется искать. Но было бы замечательно, если бы нашелся кто-нибудь, кто с этим уже сталкивался :)

P.S. Скажу наперед, может, на что-то повлияет, есть строки, длина которых - 2000 символов.

Добавлено: 10 июн 2005, 23:41
Natashka
Так может кто-нибудь может привести пример, как он обрезал строки?
В приципе-то, несложного примера будет достаточно. Просто чтобы самостоятельно искать требуется много времени.

Добавлено: 11 июн 2005, 02:55
Oscar
Natashka,
приведи, пожалуйста, пример того, что работает (вывод без обрезания).

Я уверен, что при помощи регулярных выражений можно добиться решения твоей проблемы.

Вот только мой опыт программиронания на Перле не достаточно велик.

Добавлено: 11 июн 2005, 18:27
Natashka
Какой пример? Вот так, как написано, пока и работает. Т.е. если считывается значение тэга TF_ERSTDAT 11062005182645, то он и выводит 11062005182645, а надо, чтобы секунды обрезались, чтобы оставалось только 110620051826.

Опыта программирования на перле, к сожалению, почти ни у кого из моих знакомых нет. Потому-то так и тяжело =(

Добавлено: 12 июн 2005, 12:21
Absurd
В принципе, в регулярных выражениях перла помимо * (от нуля до бесконечности), + (от одного до бесконечности) и ? (ноль или один) есть еще и ограничитель вида {нижний предел,верхний предел}
Допустимы также
{,верхний предел} (нижний предел считается равным нулю)
{нижний предел,} (верхний предел считается равным бесконечности)

Не совсем понял твой язык регекспов, но попробую разгадать

1) Сначала идет символ %
2) Потом идет от 1 до N важных цифр
3) Потом может идти от нуля до бесконечности цифр которые надо откусить
4) Потом будет идти символ %

Решение

1) сначала просто -% Это означает что этот символ должен быть обязательно и в единственном экземпляре.
2) потом - (\d{1,4}) Символы с бекслэшем обозначают некий класс символов. Нам нужен класс "digit", котрый обозначется как \d.кроме того, он нам нужен не в единственном экземпляре а от одного до четырех. Поэтому ставим квалификатор {1,4}. Все выражение для нас важно, это именно та информация которую надо извлечь из текста, поэтому берем ее в скобки. При применеии этого регулярного выражения к строке интерпретатор сохранит эту информацию в переменной $1
3) опять пользуемся классом \d, но ставим квалификатор *, который означает что этих (лишних) цифр может не быть, или может быть сколько угодно. Эти лишнии цифры нам не нужны, поэтому в скобки мы их не берем.

Потом мы приненяем рассуждения 1-3 к оставшейся части


/%(\d{1,4})\d*%(\d{1,4})\d*%(\d{1,4})\d*%(\d{1,2})\d*/

Код: Выделить всё

my $txt = "%12345%123%1234567%12345678";


if ($txt =~ /%(\d{1,4})\d*%(\d{1,4})\d*%(\d{1,4})\d*%(\d{1,2})\d*/) {
	print "$1 $2 $3 $4";
}
output:
1234 123 1234 12

Добавлено: 13 июн 2005, 10:29
chur
Для ограничения максимальной длины строки в функции printf надо использовать точку:

Код: Выделить всё

printf "%.5s", 'abcdefg'; #выведет 'abcde'
Если просто нужно убрать два последних символа, то можно вызвать два раза функцию chop, либо substr следующим образом:

Код: Выделить всё

substr($a, -2, 2, '')

Добавлено: 13 июн 2005, 23:26
Natashka
Пасибо всем большое!
Искренняя благодарность и респект!