为什么我的perl脚本没有从我的正则表达式匹配中找到错误的缩进

时间:2011-08-12 19:10:58

标签: regex perl coding-style indentation

我的工作编码标准使用此括号缩进:

some declaration
    {
    stuff = other stuff;
    };

control structure, function, etc()
    {
    more stuff;
    for(some amount of time)
        {
        do something;
        }
    more and more stuff;
    }

我正在编写一个perl脚本来检测不正确的缩进。这是我在while(<some-file-handle>)

的正文中所拥有的内容
# $prev holds the previous line in the file
# $current holds the current in the file
if($prev =~ /^(\t*)[^;]+$/ and $current =~ /^(?<=!$1\t)[\{\}].+$/) {
    print "$file @ line ${.}: Bracket indentation incorrect\n";
}

在这里,我正在尝试匹配:

  • $prev:一行不以分号结尾,后跟......
  • $current:一行,其中有前导标签数+上一行的1个。

此刻似乎没有任何匹配。

4 个答案:

答案 0 :(得分:0)

$ prev变量需要进行一些修改。

应该是\t*然后.+,而不是semicolon

另外,$ current应该是:

;{} 而非结尾的任何内容,包含前导标签的数量+上一行的1个。

修改 尝试$prev

的perl代码
#!/usr/bin/perl -l

open(FP,"example.cpp");

while(<FP>)
{
  if($_ =~ /^(\t*)[^;]+$/) {
    print "got the line: $_";
  }
}

close(FP);

// example.cpp

for(int i = 0;i<10;i++)
{
  //not this;
  //but this
}

//输出

got the line: {

got the line:   //but this

got the line: }

它没有检测到for循环的行... 我错过了什么......

答案 1 :(得分:0)

并且您打算只计算标签(而不是空格)以进行缩进?

编写这种检查器很复杂。只要想想使用不应该改变缩进的大括号的所有可能的构造:

s{some}{thing}g

qw{ a b c }

grep { defined } @a

print "This is just a { provided to confuse";

print <<END;
This {
  $is = not $code
}
END

但无论如何,如果上述问题对您来说并不重要,请考虑半结肠在您的正则表达式中是否重要。毕竟,写作

while($ok)
    {
    sort { some_op($_) }
        grep { check($_} }
        my_func(
            map { $_->[0] } @list
        );
    }

应该可以。

答案 2 :(得分:0)

我看到了几个问题......

  1. 你的上一个正则表达式匹配所有没有;任何地方。它将在像(对于int x = 1; x&lt; 10; x ++)
  2. 这样的行上断开
  3. 如果开口的缩进{不正确,则不会检测到。
  4. 尝试这一点,它只关心你是否有{;(后跟任何空格)最后

    /^(\s*).*[^{;]\s*$/
    

    现在你应该改变你的策略,这样如果你看到一条不以{或;你增加缩进计数器。

    如果你看到以}结尾的行;或者}减少你的缩进计数器。

    将所有行与此

    进行比较
    /^\t{$counter}[^\s]/ 
    

    所以......

    $counter = 0;
    
    if (!($curr =~ /^\t{$counter}[^\s]/)) {
        # error detected
    }
    
    if ($curr =~ /[};]+/) {
      $counter--;
    
    } else if ($curr =~ /^(\s*).*[^{;]\s*$/) }
      $counter++;
    
    }
    

    很抱歉没有根据您的标准设置我的代码...:)

答案 3 :(得分:0)

你考虑过Perltidy吗?

Perltidy是一个Perl脚本,它将Perl代码重新格式化为set标准。当然,你所拥有的不是Perl标准的一部分,但你可以通过Perltidy使用的配置文件调整花括号。如果所有其他方法都失败了,您可以破解代码。毕竟,Perltidy只是一个Perl脚本。

我还没有真正使用它,但它可能值得研究。您的问题是尝试找到所有各种边缘情况,并确保您正确处理它们。您可以解析100个程序,发现第101个显示格式化程序中的问题。 Perltidy已被成千上万的人用于数百万行代码。如果有问题,可能已经找到了。