Perl Grep несколько шаблонов - PullRequest
0 голосов
/ 15 июня 2011

У меня есть файл, скажем, он называется

                                 filename.c

Я пытаюсь выяснить, используется ли файл одним из следующих способов

                          1.  include("filename.c");
                          2.   require("filename.c");
                          3.   x = new filename() ; 
                          4.   class new_class extends filename
                          5.   class new_class implements filename
                          6.   filename::function()

Мне интересноПозволит ли perl мне выполнять все вышеуказанные поиски сразу, или я просто должен делать их один за другим?

А также я не очень хорошо разбираюсь в регулярных выражениях, поэтому мне интересно, как я могу выполнить поиск по строке? Расширяет имя файла?Заранее спасибо.

Ответы [ 4 ]

1 голос
/ 15 июня 2011

что не так с grep?

W="filename"
find . -type f -print0 | xargs -0 grep -ilP "include(\"$W\.c\")|require(\"$W\.c\")|x\s*=\s*new\s+$W()|class\s+new_class\s+extends\s+$W|class\s+new_class\s+implements\s+$W|$W::function()"
1 голос
/ 15 июня 2011

Использовать Файл :: Найти

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

Вы можете сохранить этот скрипт в файле, скажем script.pl, и назвать его так:

perl script.pl dir1 dir2 и dir1 и dir2 будут подвергнуты глубокому поиску. Sub wanted будет вызываться во всех файлах и каталогах, но я добавил проверку, чтобы немедленно вернуться, если текущая запись ($ _) является каталогом.

ПРИМЕЧАНИЕ. Поскольку я добавил / x к регулярному выражению, вы можете добавить пробел, чтобы разбить регулярное выражение на несколько строк, чтобы его было легче читать. Вы можете добавить /i, если вам нужен поиск без учета регистра.

use strict;
use warnings;
use File::Find;

my $filename_to_check = 'filename'; ## or you could set it as first arg and say
                                    ## my $filename_to_check = shift @#ARGV;
my $filename_check = qr/(?:
            include\s*\(\s*"$filename_to_check\.c"\s*\)|
            require\s*\(\s*"$filename_to_check\.c"\s*\)|
            new\s+$filename_to_check\s*\(|
            class\s+\S+\s+extends\s+$filename_to_check|
            class\s+\S+\s+implements\s+$filename_to_check|
            $filename_to_check\::[\w]+\s*\(\s*\)
        )/x;

&find(\&wanted,@ARGV); ## where ARGV has all the directories you want to search

sub wanted
{
    ## don't try to open directories like files
    ## you can also return (exit wanted for current file) based on file extension.
    ##    or other arbitrary reasons.
    return if -d $_;

    eval
    {
        open F,$_ || die "Can't read $File::Find::name, $!\n";
        my $found = 0;
        while(<F>)
        {
            if($_ =~ $filename_check)
            {
                $found ++;
                print $_;
            }
        }
        if($found)
        {
            print "Found $found matches in file, $File::Find::name\n";
        }
    };
    if($@)
    {
        print STDERR $@;
    }
}
0 голосов
/ 15 июня 2011

Для "класса BLAH расширяет FOO" вам может понадобиться что-то вроде

/class\s+\S+\s+extends\s+\S+/
  • \ s, совпадающее с любым типом пробела,
  • \ S соответствует любому типу, не содержащему пробела,
  • суффикс + означает «один или несколько из», поэтому «\ s +» означает «один или несколько пробелов».
0 голосов
/ 15 июня 2011

Я думаю, вы ищете |, регулярное выражение "или" оператор.

/include\("filename\.c"\);|require\("filename\.c"\);|x = new filename\(\) ;|class new_class extends filename|class new_class implements filename|filename::function\(\)\*/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...