Perl удаляет ненужные строки из строки - PullRequest
0 голосов
/ 15 марта 2011

Я пишу скрипт на Perl. Я хочу отфильтровать строки, которые не соответствуют заданному регулярному выражению. Проблема в том, что я не могу этого сделать.

У меня есть следующие строки:

"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/SeverityLevelCounter"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/FilterSet"
"com/puppycrawl/tools/checkstyle/Checker" -> "java/util/Locale"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/CheckstyleException"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/PackageObjectFactory"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/DefaultContext"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/AutomaticBean"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/FileSetCheck"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/Filter"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/AuditListener"
"com/puppycrawl/tools/checkstyle/Checker" -> "java/lang/StringBuilder"
"com/puppycrawl/tools/checkstyle/Checker" -> "java/lang/Exception"
"com/puppycrawl/tools/checkstyle/Checker" -> "java/io/File"

И я хочу удалить все те, которые не начинаются с com/puppycrawl/tools/checkstyle/ после ->

Пока мой сценарий выглядит так:

#! /usr/bin/perl -s

use File::Find;

our ($roll);

$dir = shift or die("Folder missing\n");
$prefix = shift;


$command = "javap -v";
$extension = "class";
$temp_file = "temp.tmp";

find(\&wanted, $dir);
sub wanted 
{
    if ($_ =~ /\.$extension$/)
    {
        push (@class_files, $File::Find::name);
    }
}

print "digraph G\n{\n";
    print "node [shape=box]\n";

    foreach $class (@class_files) {
        $class=~ s/(.*)\..*/$1/;
        $_result= `$command $class | grep " = class"`;
        $_result=~ s/.*\/\/ */\"$class\" -> /g;

        $_line.=$_result;
    }

    $_line=~ s/"$dir\//"/g;
    $_line=~ s/\[[A-Z]?//g;
    $_line=~ s/\;//g;
    $_line=~ s/->\s*(.*)/-> \"$1\"/g;   

Ответы [ 6 ]

4 голосов
/ 15 марта 2011

Нечто подобное может быть?

   perl -ne 'print unless /->\s+"com\/puppycrawl\/tools\/checkstyle"/' filename.txt
2 голосов
/ 16 марта 2011

В конце вашего скрипта вы можете добавить следующую строку:

$_line = join("\n", grep { $_ !~ m{->\s+"com/puppycrawl/tools/checkstyle} }
                       split(/\n/, $_line) );

Это (от задней части к передней части)

а.) Разбивает $_line на отдельные строки

b.) Отфильтровывает нежелательные строки с помощью grep

в.) Снова соединяет строки в $ _line

1 голос
/ 16 марта 2011

Вы знаете, что вам не нужно использовать косую черту для оператора регулярных выражений.Правильно?

foreach my $line (@list) {
   print "$line" if ($line =~ m(->\s+com/puppycrawl/tools/checkstyle));
}

Вы можете использовать любой символ, который хотите после m:

foreach my $line (@list) {
   print "$line" if ($line =~ m#->\s+"com/puppycrawl/tools/checkstyle#);
}

или

foreach my $line (@list) {
   print "$line" unless ($line =~ m@->\s+com/puppycrawl/tools/checkstyle@);
}

и т. Д.

Это значительно облегчает работу с регулярными выражениями, которые содержат косую черту.

Кстати, вы можете читать весь файл сразу в массив:

open (MY_FILE, "file.txt") or die qq(A slow and painful death\n);
my @list = <MY_FILE>;
close (MY_FILE);    #No longer needed. It's in @list.

Кроме того, я ненавижуFile::Find потому что это нарушает все правила при написании модуля.Я написал свою собственную, которая не требует, чтобы вы помещали всю программу в нужную подпрограмму или использовали глобальные переменные: http://db.tt/SSAw1x3.

1 голос
/ 15 марта 2011

Сделайте это после создания списка @class_spec (который вы можете сделать с помощью my @class_spec = split(/\n/, @class_files);:

# only keep the class specifiations that match the desired pattern
@class_spec = grep {
    m# -> com/puppycrawl/tools/checkstyle/#;
} @class_spec;
0 голосов
/ 16 марта 2011

возможно что-то подобное может помочь

use strict;
use warnings;

# the desired string
my $to_match = 'com/puppycrawl/tools/checkstyle/';

my $pattern = qr/   # compile the regex
    ->      # start matching from the arrow ->
    \s+     # which is followed by a space
    "       # and then a "
    $to_match   # finally the desired string
    /x; 

while (my $line = <DATA>) {
    chomp $line;
    next if $line =~ /^\s*$/; 
    next unless $line =~ /$pattern/;
    print $line, "\n";
}


__DATA__
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/SeverityLevelCounter"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/FilterSet"
"com/puppycrawl/tools/checkstyle/Checker" -> "java/util/Locale"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/CheckstyleException"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/PackageObjectFactory"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/DefaultContext"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/AutomaticBean"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/FileSetCheck"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/Filter"
"com/puppycrawl/tools/checkstyle/Checker" -> "com/puppycrawl/tools/checkstyle/api/AuditListener"
"com/puppycrawl/tools/checkstyle/Checker" -> "java/lang/StringBuilder"
"com/puppycrawl/tools/checkstyle/Checker" -> "java/lang/Exception"
"com/puppycrawl/tools/checkstyle/Checker" -> "java/io/File"
0 голосов
/ 15 марта 2011

Использование обратных галочек в скалярном контексте дает вывод программы в одной строке вместе с головной болью о том, какие символы могут соответствовать символу новой строки и будет ли жадное регулярное выражение поглощать несколько строк. Возможно, ваш код был бы более понятным, если бы вы использовали обратные ссылки в контексте списка:

foreach $class (@class_files) {
    $class=~ s/(.*)\..*/$1/;
    my @_result = `$command $class | grep " = class"`;
    s{.*// *}{"$class" -> }g foreach @_result;
    $line .= join'', @_result;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...