【问题标题】:Please explain this Perl regular expression请解释这个 Perl 正则表达式
【发布时间】:2010-09-27 17:25:09
【问题描述】:
    $rowfetch =~ s/['-]//g; #All chars inside the [ ] will be filtered out.
    $rowfetch =~ m/(\w+), ?(.)/;
    printf $fh lc($2.$1);

我昨天得到了构建这个正则表达式的帮助,但我并不完全理解它。

它需要一个像 Parisi、Kenneth 这样的名字并打印出 kparisi

已知:
s/ = 替代
m/ = 匹配


我尝试搜索其余部分,但找不到任何真正有助于解释它的内容。

我也不明白=~ 应该如何评估为真或假,但在这种情况下,它正在修改字符串。

【问题讨论】:

  • 您应该采用 Konrad 的解决方案(在我修复它之后)。那个很容易理解。
  • 哦,我不知道你已经修复了它...我会测试它并感谢...虽然 Vinko 的解决方案对我来说非常有效。我不知道您是否看到我们的评论线程,但他帮助摆脱了字符串中的其他一些字符。如果你的工作有效,我会告诉你的,谢谢。
  • 它将 Parisi, Kenneth 变成 kparisienneth
    $rowfetch =~ s/(\w+),\s(\w)/$2$1/;
    $rowfetch =~ s/([a-z]+)\s([a-z])/$2$1/i;
    $rowfetch = lc $rowfetch;
  • nm 我认为这需要 html...顺便说一句,有什么方法可以直接向该站点上的某人发送消息?我显然是新来的

标签: regex perl string


【解决方案1】:

我发现YAPE::Regex::Explain 模块非常有用 -

C:\>perl -e "use YAPE::Regex::Explain;print YAPE::Regex::Explain->new(qr/['-])->explain;"
The regular expression:

(?-imsx:['-])

matches as follows:

NODE                     EXPLANATION
----------------------------------------------------------------------
(?-imsx:                 group, but do not capture (case-sensitive)
                         (with ^ and $ matching normally) (with . not
                         matching \n) (matching whitespace and #
                         normally):
----------------------------------------------------------------------
  ['-]                     any character of: ''', '-'
----------------------------------------------------------------------
)                        end of grouping
----------------------------------------------------------------------



C:\>perl -e "use YAPE::Regex::Explain; print YAPE::Regex::Explain->new(qr/(\w+), ?(.)/)->explain;"
The regular expression:

(?-imsx:(\w+), ?(.))

matches as follows:

NODE                     EXPLANATION
----------------------------------------------------------------------
(?-imsx:                 group, but do not capture (case-sensitive)
                         (with ^ and $ matching normally) (with . not
                         matching \n) (matching whitespace and #
                         normally):
----------------------------------------------------------------------
  (                        group and capture to \1:
----------------------------------------------------------------------
    \w+                      word characters (a-z, A-Z, 0-9, _) (1 or
                             more times (matching the most amount
                             possible))
----------------------------------------------------------------------
  )                        end of \1
----------------------------------------------------------------------
  ,                        ','
----------------------------------------------------------------------
   ?                       ' ' (optional (matching the most amount
                           possible))
----------------------------------------------------------------------
  (                        group and capture to \2:
----------------------------------------------------------------------
    .                        any character except \n
----------------------------------------------------------------------
  )                        end of \2
----------------------------------------------------------------------
)                        end of grouping
----------------------------------------------------------------------

C:\>

【讨论】:

  • 哇哦等一下这是什么干草?感谢您的帮助,但这只是看起来和阅读很奇怪......所有的----------------------是怎么回事?
  • 没关系...它只是作为预代码出现...上次我查看它时,它是常规格式
  • 它是 YAPE::Regex 的输出,在命令行上看起来会更好。关键是有一个简洁的工具可以帮助解释正则表达式。
【解决方案2】:

我将其中一个cheat sheets 固定在我的立方体墙上以备不时之需。 Google for regular expression cheat sheet 寻找其他人。

添加到您已经知道的内容:

  g -- search globally throughout the string
  + -- match at least one, but as many as possible
  ? -- match 0 or 1
  . -- match any character
 () -- group these together
  , -- a plain comma, no special meaning
 [] -- match any character inside the brackets
 \w -- match any word character

神奇之处在于分组——匹配表达式使用分组并将它们放入变量 $1 和 $2 中。在这种情况下,$1 匹配逗号前的单词,$2 匹配逗号后空格后面的第一个字符。

【讨论】:

  • 是的,当我发现哈哈时,我立即将其从我的“已知”中删除 - 愚蠢
  • 只是一个小补充,逗号后面的空格是可选的(由于?)
  • @Dashogun。正确,但他的示例中有空格。
【解决方案3】:

下载“正则表达式教练”并进行探索。 考虑购买“掌握正则表达式”,因为它会带你走过这个雷区。这是我见过的最好的排版书籍之一,内容丰富且深入人心。

【讨论】:

    【解决方案4】:

    第一行:[]('和-)中的字符被匹配并替换为空(s),因此被删除。 /g 表示全局,将尝试匹配字符串中的所有内容。

    第二行:\w 表示一个单词字符,+ 表示不止一次。 ?表示 0 或一次。 “。”意味着任何东西。所以它的意思是找到任何一个以上找到的单词字符,后跟一个逗号,后跟一个空格零或一次,然后是任意字符之一。

    【讨论】:

      【解决方案5】:

      iirc =~ 表示等于匹配(cf "~" 如果匹配则单独返回 true)

      【讨论】:

        【解决方案6】:

        请注意,如果输入的格式不正确,给定的代码会严重失败。这就是我要做的:

        $rowfetch =~ s/[ '-]//g; #All chars inside the [ ] will be filtered out.
        if($rowfetch =~ m/(\w+),([a-z])/i) {
            printf $fh lc($2.$1);
        }
        

        $1-$9 位置变量保存最后一次成功的匹配,但在匹配失败的情况下它们不会被重置。这意味着如果正则表达式不匹配,$1 和 $2 将不会被删除,你最终会得到与你想要的不同的东西。

        我还稍微改变了正则表达式。第一行还删除了空格。由于您似乎正在创建用户名或电子邮件地址,因此您不需要空格。第二行更加严格,以确保 $2 是一个字母,而不是其他字符。最后的 'i' 告诉 perl 使所有字母匹配不区分大小写。有了它,我就不必制作第二部分 ([a-zA-Z])。

        【讨论】:

          【解决方案7】:

          =~ 将左侧的表达式(字符串)与右侧的正则表达式匹配,它不会修改字符串。 Asa 的副作用是将变量 $1, $2, ... 设置为匹配的括号部分。

          在您的情况下,第一个括号将匹配“(\w+)”(单词字符重复一次或多次,第二个将匹配“(.)”(给定名称的第一个字母。“ ?”表达式将匹配一个可选的空格。

          【讨论】:

            【解决方案8】:
            $lhs =~ s/foo/bar/g;
            

            s/ 运算符是 Perl 中的修改正则表达式 - 您将 LHS 与右侧的第一部分 (foo) 匹配。第二部分指定替换第一部分中的匹配项 (bar)。所以“Lafooey”转到“Labarey”。

            在您的问题中,目的是删除所有 ' 和 - 就像在“O'Hanlon”和“Chalmonly-Witherington-Smyth”中一样。

            然后它匹配“姓氏,名字的第一个字符”。括号将这些匹配的值放入变量$1$2

            并打印“F”+“Lastname”的小写字母,因为这些是$2$1 中的值。

            最后,您可以根据电话簿样式列表中的人的真实姓名为系统提供一个可行的用户名。

            【讨论】:

              【解决方案9】:

              YAPE::Regex::Explain 有一个很棒的 Web 前端。

              这里是s/['-]//g的解释

              对于m/(\w+), ?(.)/

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2012-07-16
                • 2012-01-13
                • 1970-01-01
                • 1970-01-01
                • 2013-12-31
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多