有没有更好的方法用/x 编写 Perl 正则表达式,这样代码仍然易于阅读? [英] Is there a better way to write Perl regexes with /x so the code is still easy to read?

查看:89
本文介绍了有没有更好的方法用/x 编写 Perl 正则表达式,这样代码仍然易于阅读?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的一个脚本上运行 Perl::Critic,并收到以下消息:

I ran Perl::Critic on one of my scripts, and got this message:

Regular expression without "/x" flag at line 21, column 26. See page 236 of PBP.

我查了政策信息此处,我知道在扩展模式下编写正则表达式将有助于查看代码的任何人.

I looked up the policy information here, and I understand that writing regular expressions in extended mode will help anyone who is looking at the code.

但是,我被困在如何将我的代码转换为使用/x 标志.

However, I am stuck as how to convert my code to use the /x flag.

CPAN 示例:

# Match a single-quoted string efficiently...

m{'[^\\']*(?:\\.[^\\']*)*'};  #Huh?

# Same thing with extended format...

m{
    '           # an opening single quote
    [^\\']      # any non-special chars (i.e. not backslash or single quote)
    (?:         # then all of...
        \\ .    #    any explicitly backslashed char
        [^\\']* #    followed by an non-special chars
    )*          # ...repeated zero or more times
    '           # a closing single quote
}x;

如果你只看正则表达式,这是有道理的.

This makes sense if you only look at the regex.

我的代码:

if ($line =~ /^\s*package\s+(\S+);/ ) {

我不确定如何在 if 语句中使用扩展的正则表达式.我可以这样写:

I am not exactly sure how to use an extended regex inside of an if statement. I can write it like this:

    if (
        $line =~ /
        ^\s*    # starting with zero or more spaces
        package
        \s+     # at least one space
        (\S+)   # capture any non-space characters
        ;       # ending in a semi-colon
        /x
      )
    {

这行得通,但我认为这几乎比原版更难阅读.有没有更好的方法(或最佳实践方法)来写这个?我想我可以使用 qr//创建一个变量.

And this works, but I think this is almost harder to read than the original. Is there a better way (or a best practice way) to write this? I guess I could create a variable using qr//.

我并不是真的在寻找关于重写这个特定正则表达式的建议(尽管如果我能改进它,我会接受建议) - 我更多的是寻找关于如何在 if 中扩展正则表达式的建议声明.

I'm not really looking for advice on re-writing this specific regex (although if I can improve it, I'll take advice) - I'm more looking for advice on how to expand a regex inside of an if statement.

我知道 Perl::Critic 只是一个指南,但遵循它会很好.

I know Perl::Critic is just a guideline, but it would be nice to follow it.

提前致谢!

因此,在收到一些答案后,我很清楚,并不总是需要使用注释制作正则表达式多行.了解基本正则表达式的人应该能够理解我的示例在做什么 - 我添加的评论可能有点不必要和冗长.我喜欢使用扩展正则表达式标志的想法,但仍然在正则表达式中嵌入空格以使正则表达式的每个部分更加清晰.感谢所有的投入!

So after receiving a few answers, it became clear to me that making a regex multi-line with comments is not always necessary. People who understand basic regex should be able to understand what my example was doing - the comments I added were maybe a little unnecessary and verbose. I like the idea of using the extended regex flag, but still embedding spaces in the regex to make each part of the regex a little more clear. Thanks for all the input!

推荐答案

好吧,我真的不认为你应该在这个上浪费竖屏空间.另一方面,如果我将这个模式写成多行,我会使用大括号并缩进模式:

Well, I really don't think you should waste vertical screen real estate on this. On the other hand, if I were to write this pattern over several lines, I would have used braces and indented the pattern:

if ($line =~ m{
        \A \s*
        package
        \s+
        (\S+)
        \s* ;
    }x 
) {

恕我直言,以下版本完全没问题:

IMHO, the following version is perfectly fine:

if ( $line =~ m{ \A \s* package \s+ (\S+) \s* ; }x  ) {

在获得 m//x 的好处方面.

in terms of getting the benefit of m//x.

在这种情况下,注释完全没有必要,因为您没有做任何棘手的事情.我确实在分​​号之前添加了 \s* ,因为有时人们会将分号与包名分开,这不应该破坏你的匹配.

The comments are completely unnecessary in this case because you are not doing anything tricky. I did add \s* before the semi-colon because sometimes people set the semi-colon apart from the package name and that should not throw off your match.

这篇关于有没有更好的方法用/x 编写 Perl 正则表达式,这样代码仍然易于阅读?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆