Perl 字符串正则表达式 - 需要解释
Perl String Regular Expression - Need Explanation
我对 Perl 还很陌生。我有以下代码片段可以正常工作,但我不完全理解它:
for ($i = 1; $i <= $pop->Count(); $i++) {
foreach ( $pop->Head( $i ) ) {
/^(From|Subject):\s+/i and print $_, "\n";
}
}
$pop->Head是函数Mail::POP3Client返回的字符串或字符串数组,是一堆邮件的header。第 3 行是某种正则表达式,它从 header 中提取 FROM 和 SUBJECT。
我的问题是打印函数如何只打印发件人和主题而不打印 header 中的所有其他内容? "and" 是什么意思 - 这肯定不能是布尔值,可以吗?最重要的是,我想将 From 字符串放入它自己的变量(我的 $fromline)中。我该怎么做?
我希望这对一些 Perl 专业人士来说很容易,它让我感到困惑!
提前致谢。
合乎逻辑的and
短路。如果左侧的计算结果为真——也就是说,如果正则表达式匹配——它会计算右侧的值,即 print
.
如果左边的表达式为假,则不需要计算右边的值,因为最终结果仍然是假,所以它会跳过它。
另请参阅:perldoc perlop
ARGHHH...我在输入答案时编辑了问题。好吧,抛开我的答案中不再相关的部分,并专注于具体问题:
外层循环遍历邮箱中的所有邮件。
内循环没有指定循环变量,所以使用特殊变量$_
。
在通过内部循环的每次迭代中,$_
是来自消息编号 $i
.
的一行 header
/^(From|Subject):\s+/i and print $_, "\n";
这一行的第一部分,直到 and
是一个模式。我们没有指定如何处理该模式,因此它隐式匹配 $_
。 (这是让 $_
与众不同的原因之一。)这给了我们一个 yes/no 测试:模式是否匹配 header 行?
该模式测试该项目是否以 (<
) 单词 "From" 或 "Subject" 中的任何一个开头,后跟一个冒号和一个或多个空白字符。 (这不是匹配 RFC 822 header 的正确模式。空格是 可选的 在冒号的 both 两侧。模式应该更恰当的是 /^(From|Subject)\s*:\s*/i
。但这是一个单独的问题。)模式末尾的 i
表示忽略大小写,因此 from
或 SUBJECT
就可以了。
and
表示如果匹配则继续计算(即执行)表达式。如果没有匹配项,则忽略 and
之后的内容。
表达式的其余部分打印 header 行 ($_
) 和一个换行符 ("\n"
)。
在 perl 中,and
和 or
是布尔运算符。它们是 &&
和 ||
的同义词,只是它们的优先级要低得多,因此更容易编写 short-ciruit 表达式,而不会因括号过多而混乱。
将 From 行捕获到单独变量中的最小更改是将以下行添加到内部循环:
/^From\s*:\s*(.*)$/i and $fromline = ;
你或许还应该输入
$fromline = undef
在循环之前,您可以在循环之后测试是否有 From: 行。
还有其他方法可以做到。事实上,这是 perl 的咒语之一:"There's more than one way to do it." 在将余额存储在 $fromline
之前,我已经从行的开头删除了 "From: ",但我不知道您的需求。
我对 Perl 还很陌生。我有以下代码片段可以正常工作,但我不完全理解它:
for ($i = 1; $i <= $pop->Count(); $i++) {
foreach ( $pop->Head( $i ) ) {
/^(From|Subject):\s+/i and print $_, "\n";
}
}
$pop->Head是函数Mail::POP3Client返回的字符串或字符串数组,是一堆邮件的header。第 3 行是某种正则表达式,它从 header 中提取 FROM 和 SUBJECT。
我的问题是打印函数如何只打印发件人和主题而不打印 header 中的所有其他内容? "and" 是什么意思 - 这肯定不能是布尔值,可以吗?最重要的是,我想将 From 字符串放入它自己的变量(我的 $fromline)中。我该怎么做?
我希望这对一些 Perl 专业人士来说很容易,它让我感到困惑!
提前致谢。
合乎逻辑的and
短路。如果左侧的计算结果为真——也就是说,如果正则表达式匹配——它会计算右侧的值,即 print
.
如果左边的表达式为假,则不需要计算右边的值,因为最终结果仍然是假,所以它会跳过它。
另请参阅:perldoc perlop
ARGHHH...我在输入答案时编辑了问题。好吧,抛开我的答案中不再相关的部分,并专注于具体问题:
外层循环遍历邮箱中的所有邮件。
内循环没有指定循环变量,所以使用特殊变量$_
。
在通过内部循环的每次迭代中,$_
是来自消息编号 $i
.
/^(From|Subject):\s+/i and print $_, "\n";
这一行的第一部分,直到 and
是一个模式。我们没有指定如何处理该模式,因此它隐式匹配 $_
。 (这是让 $_
与众不同的原因之一。)这给了我们一个 yes/no 测试:模式是否匹配 header 行?
该模式测试该项目是否以 (<
) 单词 "From" 或 "Subject" 中的任何一个开头,后跟一个冒号和一个或多个空白字符。 (这不是匹配 RFC 822 header 的正确模式。空格是 可选的 在冒号的 both 两侧。模式应该更恰当的是 /^(From|Subject)\s*:\s*/i
。但这是一个单独的问题。)模式末尾的 i
表示忽略大小写,因此 from
或 SUBJECT
就可以了。
and
表示如果匹配则继续计算(即执行)表达式。如果没有匹配项,则忽略 and
之后的内容。
表达式的其余部分打印 header 行 ($_
) 和一个换行符 ("\n"
)。
在 perl 中,and
和 or
是布尔运算符。它们是 &&
和 ||
的同义词,只是它们的优先级要低得多,因此更容易编写 short-ciruit 表达式,而不会因括号过多而混乱。
将 From 行捕获到单独变量中的最小更改是将以下行添加到内部循环:
/^From\s*:\s*(.*)$/i and $fromline = ;
你或许还应该输入
$fromline = undef
在循环之前,您可以在循环之后测试是否有 From: 行。
还有其他方法可以做到。事实上,这是 perl 的咒语之一:"There's more than one way to do it." 在将余额存储在 $fromline
之前,我已经从行的开头删除了 "From: ",但我不知道您的需求。