Лекция 14. Оператор split и функция grep
В этой лекции дается описание работы операторов и встроенных функции Perl, которые используют регулярные выражения.
Ключевые слова: split, perl, шаблон, подшаблон, класс символов, диапазон символов, метасимвол, эскейп-последовательность. обратная ссылка, альтернативный шаблон, квантификатор, минимальный квантификатор, числитель, повторитель, мнимый символ, якорь, модификатор, захватывающие скобки, незахватывающие скобки, сохраняющие скобки, нумерованная переменная, регулярное выражение.
Оператор split
Оператор разбиения split выполняет в каком-то смысле роль, противоположную роли оператора поиска т/// с модификатором g в списковом контексте. Если этот оператор т///возвращает все фрагменты текста, которые совпали с регулярным выражением, то оператор split возвращает фрагменты текста, которые не совпали с регулярным выражением, заданным ему в качестве аргумента. Оператор split разбивает исходный текст на куски, которые разделяются текстом, совпадающим с заданным регулярным выражением, и возвращает эти куски текста в виде массива. В качестве разделителя может выступать регулярное выражение, которое совпадает только с позицией в тексте, например, оператор
@lines=split Л/m, $text;
вернет в массиве @lines заданный текст, разбитый на логические строки.
Замечу, что в регулярном выражении в операторе split якорь начала текста л означает начало логической строки, даже если модификатор т не задан, поэтому оператор
@lines=split Л/. Stext;
будет работать точно так же, как и предыдущий оператор с модификатором т. Но можно это неявное правило отменить:
@lines=split /(?-m)'7, $text;
Это будет эквивалентно оператору
@lines=split ДА/, $text;
На метасимвол $ это неявное правило не распространяется.
В регулярном выражении, которое применяется в операторе split, точно так же работает интерполяция переменных и модификатор о, как и в обычных регулярных выражениях.
Оператор split можно использовать в простых случаях, например, когда надо разбить выходные данные от HTML-формы по знаку равенства, но этот оператор можно применять и в более сложных случаях. Однако оператор split перегружен разными тонкостями и исключениями, которые надо рассмотреть. В общем случае этот оператор имеет вид
split [ совпадение [ , целевой текст [ , ограничение ] ]]
Список операндов при необходимости можно заключать в скобки. Третий операнд не обязателен. Если его значение равно нулю, то это эквивалентно тому, что он не задан. Второй операнд также не обязателен, но в случае его отсутствия также должен отсутствовать и третий операнд. Не обязателен и первый операнд, оператор
split
эквивалентен вызову
split ‘ О
где первый операнд является строкой, состоящей из одного пробела. Этот вызов разобьет текст, находящийся в 5_, по пробельным символам, при этом начальные и заключительные пустые элементы созданы не будут.
Специальный первый операнд // и ‘ ‘
Специальный первый операнд//(пустое регулярное выражение) означает вовсе не применение регулярного выражения по умолчанию в качестве ограничителя для разбивки текста — операнд разбивает входной текст на отдельные символы, из которых он состоит. Например, оператор
print join split //, 'abcde';
напечатает a-b-c-d-e.
Специальный операнд ‘ ' (строка из одного пробела), разбивает заданный текст по пропускам $+, но при этом начальные (и конечные) пробельные символы игнорируются. Например, оператор
print join 1-'.split ‘ ‘ а b с de
напечатает a-b-c-de, а оператор
print join split mAs-»-/, ‘ a b с de 1;
напечатает -a-b-c-de. Как видим, первый оператор игнорирует начальные и конечные пробелы, а второй — только конечные.
Первый операнд (совпадение)
Рассмотрим варианты для первого операнда оператора split. Это может быть:
- 1. регулярное выражение.
- 2. объект регулярного выражения;
- 3. любое другое выражение, которое будет интерпретироваться как строка.
Для регулярных выражений вы можете употреблять лишь базовые модификаторы і, х, s, т, о. Если вы хотите сгруппировать подшаблоны, то используйте несохраняющие круглые скобки, т.к. захватывающие скобки имеют в этом операнде особый смысл.
Второй операнд (целевой текст)
Оператор split не изменяет целевой текст, поэтому в качестве целевого текста можно применять непосредственное значение. Если целевой текст не задан, то используется значение переменной по умолчанию
Третий операнд (ограничение)
Роль этого необязательного операнда в том, чтобы ограничить число фрагментов, на которые будет разбит заданньїіі текст. Если этот операнд отсутствует, то ограничения нет. Например, оператор
print join split ‘ * а b с de *, 3;
напечатает a-b-c de
После возврата двух элементов вернется остаток заданного текста. Если в результате текст разобьется на число частей, которое меньше заданного. то дополнительные элементы не создаются. Например:
print join split ‘ ‘' а b с de ‘,10;
Напечатается: a-b-c-de-. Мы видим, что в этой форме оператор split, в отличие от случая, когда третий операнд отсутствует, начинает возвращать конечные пустые элементы.
Также можно ограничить количество возвращаемых значений, если в качестве приемника задать список
($a,$b,$c) = split /$ге/, $text;
После заполнения заданного количества полей Perl прекратит работу оператора split. Если количество кусков текста меньше заявленного количества элементов списка, то оставшиеся элементы списка получат пустые значения.