【问题标题】:Perl String Regular Expression - Need ExplanationPerl 字符串正则表达式 - 需要说明
【发布时间】:2015-01-12 14:50:33
【问题描述】:

我对 Perl 很陌生。我有以下代码片段可以正常工作,但我不完全理解它:

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 和 Subject 而没有标题中的所有其他内容? “和”是什么意思 - 这肯定不能是布尔值,可以吗?最重要的是,我想将 From 字符串放入它自己的变量(我的 $fromline)中。我该怎么做?

我希望这对一些 Perl 专业人士来说会很容易,这让我感到困惑!

提前致谢。

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    ARGHHH... 在我输入答案时,问题已被编辑。好的,扔掉我的答案中不再相关的部分,并专注于具体问题:

    外层循环遍历邮箱中的所有邮件。
    内部循环没有指定循环变量,所以使用了特殊变量$_
    在内部循环的每次迭代中,$_ 是消息号 $i 的一个标题行。

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

    这一行的第一部分,直到and 是一个模式。我们没有指定如何处理该模式,因此它与$_ 隐式匹配。 (这是使$_ 与众不同的原因之一。)这给了我们一个是/否测试:模式是否与标题行匹配?

    该模式测试该项目是否以 (&lt;) 开头的单词“From”或“Subject”,紧跟一个冒号和一个或多个空格字符。 (这不是匹配 RFC 822 标头的正确模式。空格在冒号的 both 两侧是 可选。该模式应该更恰当地是 /^(From|Subject)\s*:\s*/i。但这是一个单独的问题。)模式末尾的i 表示忽略大小写,所以fromSUBJECT 可以。

    and 表示如果匹配,则继续评估(即执行)表达式。如果没有匹配,and 后面的任何内容都会被忽略。

    表达式的其余部分打印标题行 ($_) 和换行符 ("\n")。

    在 perl 中,andor 是布尔运算符。它们是&amp;&amp;|| 的同义词,只是它们的优先级要低得多,这样可以更轻松地编写短电路表达式,而不会因大量括号而杂乱无章。

    将 From 行捕获为单独变量的最小更改是将以下行添加到内部循环:

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

    你可能也应该放

    $fromline = undef
    

    在循环之前,您可以在循环之后测试是否有 From: 行。

    还有其他方法可以做到这一点。事实上,这就是 perl 的口头禅之一:“有不止一种方法可以做到这一点。”在将余额存储到$fromline 之前,我已经从行的开头删除了“From:”,但我不知道您的需求。

    【讨论】:

    • 该模式测试该项目是否以 ( 开头——需要更多编辑。该组也应该是非捕获的。
    【解决方案2】:

    这是一个符合逻辑的and 短路。如果左侧计算结果为真(例如,如果该正则表达式匹配),它将计算右侧,print

    如果左边的表达式为假,则不需要计算右边的表达式,因为最终结果仍然是假的,所以它会跳过它。

    另请参阅:perldoc perlop

    【讨论】:

      猜你喜欢
      • 2012-10-18
      • 2017-09-05
      • 2011-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      • 2017-12-19
      相关资源
      最近更新 更多