Реферат: Регулярные выражения в perl
Итак, чего мы достигли? Мы будем искать нечто, состоящее из двух контейнеров, разделенных единичным пробельным символом. Правый контейнер у нас будет содержать всю ту часть строки, которая находится после единичного пробельного символа. После выполнения регулярного выражения мы сможем использовать содержимое правого (ну и левого то же) контейнера по своему усмотрению. Вот такой вывод на данный момент.
Пора приступать к содержимому левого контейнера. Напомню как он выглядит
[^\s]*
Квадратные скобки определяют класс символов. Что такое класс символов? Предположим, что искомое не может быть представлено последовательностью символов, то есть подстрокой. Иначе говоря, в примере с Пупкиным мы не можем явно указать
/Pupkin/
Не важно, по каким причинам. Может быть искомое очень длинное, а может быть искомое - произвольные варианты строк, состоящих из определенных символов. Так вот в таком случае мы определим класс символов. Например символы латинского алфавита определяются таким классом
[a-zA-Z]
Заметьте как удобно - мы не указываем все символы подряд. Мы просто определяем границы с помощью метасимвола - (это как бы даже и не совсем метасимвол, а только в данном случае). Вместо перечисления цифровых символов мы можем записать
[0-9]
Хотя для цифровых символов есть более эффективное решение - метасимвол \d. Итак, у нас в левой части определен класс символов. Но какой-то интересный класс получается - вроде привязанный к началу строки. Нет, метасимвол ^ внутри класса указывает на отрицание символов класса. Это значит, что на месте этой части шаблона должен находиться любой символ, не входящий в состав класса. То есть, для примера
[^0-9]
указывает, что здесь может быть любой нецифровой символ. Так и в нашем примере. Ну а с метасимволом \s вы уже знакомы. Учитывая отрицание получаем - любой непробельный символ. Учтите, что класс определяет только множество для соответствия или отрицания, но не множество для отбора. То есть, если у вас класс, то под шаблон попадет только один символ, удовлетворяющий условию. Для того, чтобы отобрать несколько символов нужно использовать квантификатор, что мы и делаем после описания класса символов. Теперь, что бы разобраться для отбора каких строк можно воспользоваться этим шаблоном давайте напишем пример.
#!C:/per/bin/perl -w
use strict;
reg("Vasya Pupkin");
reg(" Vasya Pupkin");
reg("Vasya\t\tpupkin");
sub reg{
print "\$1=$1\n\$2=$2\n\n" if $_[0] =~ /([^\s]*)\s(.*)/;
}
В результате получится
$1=Vasya
$2=Pupkin
$1=
$2=Vasya Pupkin
$1=Vasya
$2= pupkin
Теперь давайте разберемся почему и как. Первый тест однозначно попадает под шаблон: Vasya не состоит из пробельных символов, далее следует один пробельный символ (натурально пробел), а Pupkin составляет оставшуюся часть строки. Результат второго теста у нас какой то странный. Первый контейнер у нас оказался пуст, а второй почему то содержит всю строку без ведущего пробела. С чем это связано? Да с тем, что квантификатор * означает ноль или более символов. Так как первым в строке у нас пробельный символ, в правый контейнер, согласно условию, попадает ноль непробельных символов. Далее, пробел то не входит в состав контейнеров. Ну а второй контейнер жрет всю строку до конца. Третий вариант, я думаю, понятен. Я уже говорил, что каждый символ регулярного выражения соответствует единичному. И только квантификаторы позволяют кушать несколько символов одного класса. В шаблоне контейнеры разделены одиночным пробельным символом. В левый контейнер попадает Vasya. Самым законным образом первый пробельный символ (табуляция в примере) пропускается, а правый контейнер кушает все что осталось - в том числе и второй табулятор. Таким образом, получаем Пупкина с ведущей табуляцией.
Наверное это не совсем тот результат, который мы хотели бы получить. Нафига нам ведущие пробелы. Ну вы же знаете достаточно, что бы превратить разделитель контейнеров в квантификатор. Ну так приступайте :)