scan
-
NAME
- scan — Разбор строки с использованием спецификаторов преобразования в стиле sscanf
- SYNOPSIS
- ВВЕДЕНИЕ
- ДЕТАЛИ РАЗБОРА
- НЕОБЯЗАТЕЛЬНЫЙ ПОЗИЦИОННЫЙ СПЕЦИФИКАТОР
- НЕОБЯЗАТЕЛЬНЫЙ МОДИФИКАТОР РАЗМЕРА
- ОБЯЗАТЕЛЬНЫЙ СИМВОЛ ПРЕОБРАЗОВАНИЯ
-
d
- o
- x или X
- b
- u
- i
- c
- s
- e или f или g или E или G
- [chars]
- [^chars]
- n
- o
Имя
scan — Разбор строки с использованием спецификаторов преобразования в стиле sscanfСинтаксис
scan строка формат ?имяПеременной имяПеременной ...?Введение
Эта команда анализирует подстроки из входной строки аналогично процедуре ANSI C sscanf и возвращает количество выполненных преобразований или -1, если конец входной строки достигнут до выполнения каких-либо преобразований. Строка предоставляет вход для разбора, а формат указывает, как его разбить, используя спецификаторы преобразования %, как в sscanf. Каждое имяПеременной указывает имя переменной; когда из строки сканируется подстрока, соответствующая спецификатору преобразования, подстрока присваивается соответствующей переменной. Если переменные имяПеременной не указаны, то scan работает встроеным способом, возвращая данные, которые в противном случае хранились бы в переменных, как список. В случае встроенного способа, пустая строка возвращается, если конец входной строки достигнут до выполнения каких-либо преобразований.Детали разбора
Scan работает, сканируя строку и формат вместе. Если следующий символ в формате – пробел или табуляция, то он соответствует любому количеству символов пробела в строке (включая ноль). В противном случае, если это не символ %, то он должен соответствовать следующему символу строки. Когда встречается % в формате, это означает начало спецификатора преобразования. Спецификатор преобразования содержит до четырёх полей после %: спецификатор позиции XPG3 (или *, чтобы указать, что преобразованное значение должно быть пропущено вместо присвоения какой-либо переменной); число, указывающее максимальную ширину подстроки; модификатор размера; и символ преобразования. Все эти поля необязательны, за исключением символа преобразования. Присутствующие поля должны появляться в указанном выше порядке.Когда scan находит спецификатор преобразования в формате, он сначала пропускает любые символы пробела в строке (если символ преобразования не [ или c). Затем он преобразует следующие входные символы в соответствии со спецификатором преобразования и сохраняет результат в переменной, заданной следующим аргументом к scan.
Необязательный позиционный спецификатор
Если за % следует десятичное число и $, как в “%2$d”, то используемая переменная не берется из следующего последовательного аргумента. Вместо этого она берется из аргумента, указанного числом, где 1 соответствует первой имяПеременной. Если в формате есть какие-либо позиционные спецификаторы, то все спецификаторы должны быть позиционными. Каждая имяПеременной в списке аргументов должна соответствовать точно одному спецификатору преобразования, иначе генерируется ошибка, или в случае встроенного способа любая позиция может быть указана не более одного раза, а пустые позиции заполняются пустыми строками.Необязательный модификатор размера
Модификатор размера используется только при сканировании подстроки в одно из целочисленных значений Tcl. Модификатор размера определяет допустимый диапазон целых чисел, которые могут быть сохранены в переменной или, в случае встроенного способа, в позиции в списке результатов. Синтаксически допустимые значения модификатора размера — h, L, l и ll. Значение модификатора размера h эквивалентно отсутствию модификатора размера в спецификаторе преобразования. Любое из них указывает диапазон целых чисел, которые нужно сохранить, ограниченный тем же диапазоном, что и функция int() команды expr. Модификатор размера L эквивалентен модификатору размера l. Любое из них указывает диапазон целых чисел для сохранения, ограниченный тем же диапазоном, что и функция wide() команды expr. Модификатор размера ll указывает, что диапазон целых чисел для сохранения не ограничен.Обязательный символ преобразования
Поддерживаются следующие символы преобразования:- d
- Входная подстрока должна быть десятичным целым числом. Она считывается, и целое значение сохраняется в переменной, усекаясь в соответствии со значением модификатора размера.
- o
- Входная подстрока должна быть восьмеричным целым числом. Она считывается, и целое значение сохраняется в переменной, усекаясь в соответствии со значением модификатора размера.
- x или X
- Входная подстрока должна быть шестнадцатеричным целым числом. Она считывается, и целое значение сохраняется в переменной, усекаясь в соответствии со значением модификатора размера.
- b
- Входная подстрока должна быть двоичным целым числом. Она считывается, и целое значение сохраняется в переменной, усекаясь в соответствии со значением модификатора размера.
- u
- Входная подстрока должна быть десятичным целым числом. Целое значение усекается в соответствии со значением модификатора размера, и соответствующее беззнаковое значение для этого усечённого диапазона вычисляется и сохраняется в переменной как десятичная строка. Преобразование не имеет смысла без ссылки на диапазон усечения, поэтому модификатор ll не допускается в сочетании с символом преобразования u.
- i
- Входная подстрока должна быть целым числом. Основание (т.е. десятичное, двоичное, восьмеричное или шестнадцатеричное) определяется так же, как описано в команде expr. Целое значение сохраняется в переменной, усекаясь в соответствии со значением модификатора размера.
- c
- Считывается один символ, и его значение Юникод сохраняется в переменной как целочисленное значение. Начальные пробелы не пропускаются в этом случае, поэтому входная подстрока может быть символом пробела.
- s
- Входная подстрока состоит из всех символов до следующего символа пробела; символы копируются в переменную.
- e или f или g или E или G
- Входная подстрока должна быть числом с плавающей запятой, состоящим из необязательного знака, строки десятичных цифр, возможно содержащей десятичную точку, и необязательного показателя степени, состоящего из e или E, за которым следует необязательный знак и строка десятичных цифр. Она считывается и сохраняется в переменной как значение с плавающей запятой.
- [chars]
- Входная подстрока состоит из одного или нескольких символов в chars. Соответствующая строка сохраняется в переменной. Если первый символ в скобках – ], то он обрабатывается как часть chars, а не как закрывающая скобка для набора. Если chars содержит последовательность вида a-b, то любой символ между a и b (включительно) будет соответствовать. Если первый или последний символ в скобках – -, то он обрабатывается как часть chars, а не как указание диапазона.
- [^chars]
- Входная подстрока состоит из одного или нескольких символов, не входящих в chars. Соответствующая строка сохраняется в переменной. Если символ сразу после ^ – ], то он обрабатывается как часть набора, а не как закрывающая скобка для набора. Если chars содержит последовательность вида a-b, то любой символ между a и b (включительно) будет исключен из набора. Если первый или последний символ в скобках – -, то он обрабатывается как часть chars, а не как указание диапазона.
- n
- Вход из входной строки не потребляется. Вместо этого общее количество символов, сканированных из входной строки до сих пор, сохраняется в переменной.
Количество символов, считанных из входа для преобразования, является наибольшим числом, которое имеет смысл для данного преобразования (например, столько десятичных цифр, сколько возможно для %d, столько восьмеричных цифр, сколько возможно для %o и так далее). Входная подстрока для данного преобразования заканчивается либо при встрече символа пробела, либо при достижении максимальной ширины подстроки, что произойдёт раньше. Если в спецификаторе преобразования присутствует *, то никакой переменной не присваивается значение, и следующий аргумент сканирования не используется.
Отличия от ansi sscanf
Поведение команды scan совпадает с поведением процедуры ANSI C sscanf за исключением следующих отличий:- Спецификатор преобразования %p не поддерживается.
- Для преобразований %c значение одного символа преобразуется в десятичную строку, которая затем присваивается соответствующему имяПеременной; для этого преобразования не может быть указана ширина подстроки.
- Модификатор h всегда игнорируется, а модификаторы l и L игнорируются при преобразовании вещественных значений (т.е. для внутреннего представления используется тип double). Модификатор ll не имеет аналога в sscanf.
- Если конец входной строки достигнут до выполнения каких-либо преобразований и переменные не указаны, возвращается пустая строка.
Примеры
Преобразование символа Юникод в его числовое значение:set char "x" set value [scan $char %c]
Разбор простого цветового спецификатора вида #RRGGBB с использованием шестнадцатеричных преобразований с размерами подстрок:
set string "#08D03F" scan $string "#%2x%2x%2x" r g b
Разбор строки времени ЧЧ:ММ, учитывая, что это позволяет избежать проблем с восьмеричными числами, принудительно интерпретируя их как десятичные (если бы нам это не было важно, мы бы использовали преобразование %i):
set string "08:08" ;# *Not* octal!
if {[scan $string "%d:%d" hours minutes] != 2} {
error "not a valid time string"
}
# We have to understand numeric ranges ourselves...
if {$minutes < 0 || $minutes > 59} {
error "invalid number of minutes"
} Разбить строку на последовательности символов, не являющихся пробелами (обратите внимание на использование преобразования %n, чтобы правильно пропустить начальные пробелы):
set string " a string {with braced words} + leading space "
set words {}
while {[scan $string %s%n word length] == 2} {
lappend words $word
set string [string range $string $length end]
} Разбор простой строки координат, проверяя её полноту, явно ища завершающий символ:
set string "(5.2,-4e-2)"
# Note that the spaces before the literal parts of
# the scan pattern are significant, and that ")" is
# the Unicode character \u0029
if {
[scan $string " (%f ,%f %c" x y last] != 3
|| $last != 0x0029
} then {
error "invalid coordinate string"
}
puts "X=$x, Y=$y" Интерактивная сессия, демонстрирующая усечение целочисленных значений, определяемых модификаторами размера:
% set tcl_platform(wordSize) 4 % scan 20000000000000000000 %d 2147483647 % scan 20000000000000000000 %ld 9223372036854775807 % scan 20000000000000000000 %lld 20000000000000000000
См. также
формат, sscanf
Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/scan.htm
Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/scan.htm