2011-10-26 27 views
16

Mỗi khi tôi nhập vào một cái gì đó mã luôn cho tôi biết rằng nó tồn tại. Nhưng tôi biết một số đầu vào không tồn tại. Chuyện gì thế?Grep để tìm vật phẩm trong mảng Perl

#!/usr/bin/perl 

@array = <>; 
print "Enter the word you what to match\n"; 
chomp($match = <STDIN>); 

if (grep($match, @array)) { 
    print "found it\n"; 
} 

Trả lời

26

Các arg đầu tiên mà bạn cung cấp cho nhu cầu grep để đánh giá là đúng hay sai để cho biết đã có một trận đấu. Vì vậy, nó nên là:

# note that grep returns a list, so $matched needs to be in brackets to get the 
# actual value, otherwise $matched will just contain the number of matches 
if (my ($matched) = grep $_ eq $match, @array) { 
    print "found it: $matched\n"; 
} 

Nếu bạn cần phải phù hợp trên rất nhiều giá trị khác nhau, nó cũng có thể là đáng để bạn xem xét đưa dữ liệu array thành một hash, vì băm cho phép bạn làm điều này một cách hiệu quả mà không cần phải lặp qua danh sách.

# convert array to a hash with the array elements as the hash keys and the values are simply 1 
my %hash = map {$_ => 1} @array; 

# check if the hash contains $match 
if (defined $hash{$match}) { 
    print "found it\n"; 
} 
23

Bạn có vẻ đang sử dụng grep() như tiện ích Unix grep, điều đó sai.

Perl's grep() trong ngữ cảnh vô hướng đánh giá biểu thức cho mỗi phần tử của danh sách và trả về số lần biểu thức là đúng. Vì vậy, khi $match chứa bất kỳ giá trị "true" nào, grep($match, @array) trong ngữ cảnh vô hướng sẽ luôn trả về số lượng phần tử trong @array.

Thay vào đó, hãy thử sử dụng các nhà điều hành mô hình phù hợp:

if (grep /$match/, @array) { 
    print "found it\n"; 
} 
+0

Tôi nghĩ rằng bạn có thể tái từ này để được rõ ràng hơn - mặc dù tôi có thể xem những gì bạn có nghĩa là về đọc lại, nó ban đầu nghe có vẻ như bạn đang nói rằng 'grep' trong ngữ cảnh vô hướng trả về độ dài của' @ array'. Khi bạn (đúng) dự định, nó trả về số lần biểu thức/khối là đúng. Nếu biểu thức là * chỉ một biến * - nghĩa là không so sánh thực tế, chỉ biến '$ match', thì nó đúng cho mọi phần tử nếu biến đó là đúng (không trống, không khác, v.v.) –

+1

@Sam : Tôi đã cố gắng để viết lại nó, hy vọng nó rõ ràng hơn bây giờ. –

+1

@eugeney đọc tốt hơn tôi rất nhiều! –

1

Ngoài những gì eugene và stevenl đăng, bạn có thể gặp vấn đề với việc sử dụng cả hai <><STDIN> trong một kịch bản: <> lặp qua (= concatenating) tất cả các tệp được đặt dưới dạng đối số dòng lệnh.

Tuy nhiên, nếu một người dùng bao giờ quên để xác định một tập tin trên dòng lệnh, nó sẽ đọc từ STDIN, và mã của bạn sẽ chờ đợi mãi mãi trên đầu vào

2

Điều này có thể được thực hiện bằng List::Util 's first chức năng:

use List::Util qw/first/; 

my @array = qw/foo bar baz/; 
print first { $_ eq 'bar' } @array; 

chức năng khác từ List::Util như max, min, sum cũng có thể hữu ích cho bạn

1

tôi có thể xảy ra tha Nếu mảng của bạn chứa chuỗi "hello", và nếu bạn đang tìm kiếm "he", grep trả về true, mặc dù "anh ấy" có thể không phải là phần tử mảng.

Có lẽ,

if (grep(/^$match$/, @array)) apt hơn.

1

Bạn cũng có thể kiểm tra giá trị duy nhất trong nhiều mảng như,

if (grep /$match/, @array, @array_one, @array_two, @array_Three) 
{ 
    print "found it\n"; 
} 
+2

Chào mừng bạn đến với Stackoverflow. Bạn có thể mở rộng câu trả lời của mình thêm một chút để giải thích cách giải quyết vấn đề. – Daenarys

Các vấn đề liên quan