2008-10-15 38 views
8

Tôi gặp sự cố khi sử dụng Perl grep() với một chuỗi mà có thể chứa ký tự được hiểu là số lượng biểu thức thông thường.Có một hàm Perl để biến một chuỗi thành một regexp để sử dụng chuỗi đó làm mẫu không?

Tôi gặp lỗi sau khi mẫu grep là "g ++" vì ký hiệu '+' được hiểu là số lượng. Đây là kết quả của chương trình cho rằng sau:

1..3 
ok 1 - grep, pattern not found 
ok 2 - grep, pattern found 

Nested quantifiers in regex; marked by <-- HERE 
in m/g++ <-- HERE/at escape_regexp_quantifier.pl line 8. 

Có một modifier tôi có thể sử dụng để chỉ cho grep rằng quantifiers được bỏ qua, hoặc là có một chức năng mà sẽ thoát khỏi quantifiers?

#! /usr/bin/perl 

sub test_grep($) 
{ 
    my $filter = shift; 
    my @output = ("-r-xr-xr-x 3 root  bin  122260 Jan 23 2005 gcc", 
        "-r-xr-xr-x 4 root  bin  124844 Jan 23 2005 g++"); 
    return grep (!/$filter/, @output); 
} 

use Test::Simple tests => 2; 

ok(test_grep("foo"), "grep, pattern not found"); 
ok(test_grep("gcc"), "grep, pattern found"); 
ok(test_grep("g++"), "grep, pattern found"); 

PS: ngoài câu hỏi trả lời ở trên, tôi hoan nghênh mọi phản hồi về việc sử dụng Perl ở trên như tôi vẫn đang học. Cảm ơn

Trả lời

27

Cách thông thường là sử dụng các chỉ số \Q thoát trước khi biến của bạn, để nói Perl không để phân tích các nội dung như một biểu thức chính quy:

return grep (!/\Q$filter/, @output); 

Thay đổi dòng sản lượng mã của bạn:

 
1..3 
ok 1 - grep, pattern not found 
ok 2 - grep, pattern found 
ok 3 - grep, pattern found 
+0

lưu ý \ Q kết thúc tại \ E, có lẽ nên đảm bảo rằng \ E trong nội dung được thoát. – Hasturkun

+0

Bạn không cần phải - \ E trong mẫu * nội suy * không gây ra sự cố nào. – hexten

15

tôi nghĩ rằng bạn đang tìm kiếm quotemeta

+0

Vâng, đó là cụm từ tôi đã bỏ lỡ, cảm ơn. – philant

8

ngoài các câu hỏi câu trả lời ở trên, tôi w elcome bất kỳ thông tin phản hồi về sử dụng Perl ở trên như tôi vẫn đang học. Cảm ơn

Tôi khuyên bạn không nên sử dụng nguyên mẫu (($) sau test_grep). Họ có sử dụng của họ, nhưng không phải cho hầu hết các trường hợp và chắc chắn không phải trong này.

+0

bạn có thể giải thích về điều này không?Tôi chưa bao giờ thấy lời khuyên đó trước đây. – Alnitak

+0

Xem http://stackoverflow.com/questions/297034/why-are-perl-function-prototypes-bad – cjm

2

PS: ngoài các câu hỏi câu trả lời trên, tôi hoan nghênh bất kỳ thông tin phản hồi về Perl sử dụng ở trên như tôi vẫn là học tập.

Lời khuyên tốt nhất tôi có thể cung cấp cho lời khuyên mã hóa Perl nói chung là cài đặt Perl::Critic và sử dụng lệnh perlcritic trên mã của bạn. Nếu bạn không thể làm điều đó, bạn có thể sử dụng on-line perl critic tool. Nó sẽ giúp đỡ nếu bạn có một bản sao của Perl Best Practices tiện dụng, vì Perl::Critic đã đọc sách và sẽ cung cấp cho bạn tham chiếu đến số trang, tuy nhiên ngay cả khi bạn không có sách xung quanh, bạn vẫn có thể tìm thấy phản hồi mở rộng trong phần Perl::Critic documentation bắt đầu với Perl::Critic::Policy::.

2

Tôi khuyên bạn nên sử dụng qr để tạo đối tượng Regexp thay vì chuỗi trong trường hợp này.

ok(test_grep(qr/foo/), "grep, pattern not found"); 
ok(test_grep(qr/gcc/), "grep, pattern found"); 
ok(test_grep(qr/g\+\+/), "grep, pattern found"); 

Sau đó, bạn không cần thoát \ Q. Mặc dù bạn vẫn có thể sử dụng nó:

ok(test_grep(qr/\Qg++/), "grep, pattern found"); 
Các vấn đề liên quan