请解释这个Perl正则表达式

时间:2008-12-19 14:51:14

标签: regex perl string

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

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

它的名字像Parisi,Kenneth并打印出kparisi

Knowns :
s / =替代品m / =匹配

我试着寻找剩下的但是找不到任何真正有助于解释它的东西。

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

9 个答案:

答案 0 :(得分:22)

我发现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:\>

答案 1 :(得分:10)

我将这些cheat sheets中的一个固定在我的立方体墙上以便适用于这种场合。谷歌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匹配逗号后面的空白后面的第一个字符。

答案 2 :(得分:3)

下载“The Regex Coach”并进行探索。 考虑购买“掌握正则表达式”,因为它将带您穿过这个雷区。它是我见过的最好的排版书之一,内容丰富而且可以渗透。

答案 3 :(得分:1)

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

第二行:\ w表示单词字符,+表示不止一次。 ?表示0或一次。 “”意味着什么。所以它意味着找到不止一次找到的任何单词字符,然后是一个昏迷,然后是空格零或一次,然后是任何一个字符。

答案 4 :(得分:1)

$lhs =~ s/foo/bar/g;

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

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

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

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

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

答案 5 :(得分:1)

iirc =〜表示等于匹配(cf“〜”如果匹配则单独返回true)

答案 6 :(得分:1)

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

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

答案 7 :(得分:1)

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

$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])。

答案 8 :(得分:1)

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

以下是对s/['-]//g

的解释

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