2015-01-12 3 views
2

Я довольно новичок в Perl. У меня есть следующий фрагмент кода, который работает просто отлично, но я не до конца понимаю:Perl String Regular Expression - Пояснение

for ($i = 1; $i <= $pop->Count(); $i++) { 
    foreach ($pop->Head($i)) { 
     /^(From|Subject):\s+/i and print $_, "\n"; 
    } 
} 

$ pop-> Head является строкой или массивом строк, возвращаемых функцией Mail :: POP3Client, и это заголовки нескольких писем. Строка 3 - это какое-то регулярное выражение, которое извлекает FROM и SUBJECT из заголовка.

Мой вопрос в том, как функция печати печатает только объекты «От» и «Субъект» без всякого другого материала в заголовке? Что означает «и» - это, безусловно, не может быть логическим, и может ли это? Самое главное, я хочу поместить строку From в свою переменную (my $ fromline). Как мне это сделать?

Я надеюсь, что это будет легко для некоторых профессионалов Perl, это меня озадачило!

Заранее спасибо.

ответ

4

ARGHHH ... Вопрос был отредактирован в то время как я печатал ответ. Хорошо, выкинув часть моего ответа, которая больше не актуальна, и сосредоточив внимание на конкретных вопросах:

Внешний цикл выполняет итерацию по всем сообщениям в почтовом ящике.
Внутренний цикл не указывает переменную цикла, поэтому используется специальная переменная $_.
На каждой итерации через внутренний цикл $_ - это одна строка заголовка с номера сообщения $i.

/^(From|Subject):\s+/i and print $_, "\n"; 

В первой части этой линии, вплоть до and является шаблоном. Мы не указывали, что делать с шаблоном, поэтому он неявно сопоставляется с $_. (Это одна из вещей, которая делает $_ особенным.) Это дает нам тест «да/нет»: шаблон соответствует строке заголовка или нет?

Шаблон проверяет, начинается ли этот элемент с (<) либо из слова «От», либо «Тема», за которым следует сразу двоеточие и один или несколько пробельных символов. (Это не правильный шаблон для соответствия заголовку RFC 822. Пробел необязательный на и стороны двоеточия. Образец должен быть более /^(From|Subject)\s*:\s*/i. Но это отдельная проблема.) i в конце рисунка говорит игнорировать дело, поэтому from или SUBJECT было бы в порядке.

and говорит, что продолжает оценивать (то есть выполняет) выражение, если есть совпадение. Если нет совпадения, все последующее and игнорируется.

Остальное выражение печатает строку заголовка ($_) и новую строку ("\n").

В perl, and и or являются булевыми операторами. Они являются синонимами для && и ||, за исключением того, что они имеют гораздо более низкий приоритет, что упрощает запись коротких выражений ciruit без беспорядка из множества круглых скобок.

Наименьшее изменение, которое захватывает от линии в отдельную переменную можно было бы добавить следующую строку внутреннего цикла:

/^From\s*:\s*(.*)$/i and $fromline = $1; 

Вы, вероятно, следует также поставить

$fromline = undef 

перед циклом поэтому после цикла можно проверить, была ли строка From:.

Есть и другие способы сделать это. На самом деле, это одна из мантр perl: «Существует не один способ сделать это». Я удалил «From:» с начала строки перед сохранением баланса в $fromline, но я не знаю ваших потребностей.

+0

* Образец проверяет, начинается ли этот элемент с (<) * - требуется больше редактирования. Группа также не должна захватываться. – 7stud

0

Это логично and с коротким замыканием. Если левая сторона оценивается как истина - скажем, если это регулярное выражение совпадает - оно будет оценивать правую сторону, print.

Если выражение слева является ложным, ему не нужно оценивать правую сторону, потому что итоговый результат все равно будет ложным, поэтому он пропустит его.

Смотрите также: perldoc perlop