Lập trình · Ngôn ngữ lập trình
Hướng dẫn học lập trình Perl cơ bản cho người mới
Trả lời nhanh
Perl là ngôn ngữ kịch bản động do Larry Wall tạo ra năm 1987, nổi tiếng với xử lý văn bản và biểu thức chính quy dựng sẵn rất mạnh. Perl được cài sẵn trên hầu hết hệ thống Unix và dùng cho quản trị hệ thống, xử lý log và tin sinh học. Trang này bao gồm chạy Perl, scalar, mảng và hash, điều khiển luồng, subroutine, tham chiếu, biểu thức chính quy và xử lý lỗi với die và eval.
Mở Kiểm tra regexPerl là gì và dùng để làm gì
Perl là ngôn ngữ bậc cao, kiểu động, do Larry Wall tạo ra năm 1987. Nó được thiết kế cho xử lý văn bản và tạo báo cáo, và trở nên nổi tiếng như ngôn ngữ keo dán của quản trị hệ thống Unix và phát triển web thuở đầu. Biểu thức chính quy của Perl có ảnh hưởng lớn đến mức nhiều ngôn ngữ khác áp dụng cú pháp regex "tương thích Perl".
Ngày nay Perl được dùng cho script quản trị hệ thống, xử lý log và văn bản, tin sinh học, ứng dụng web cũ và các bộ lọc dòng lệnh một dòng. Perl được cài sẵn trên hầu hết hệ thống Linux và Unix. CPAN (Comprehensive Perl Archive Network) lưu trữ một bộ sưu tập rất lớn các module có thể tái sử dụng. Hướng dẫn này nói về Perl 5; ngôn ngữ từng được gọi là Perl 6 nay là một ngôn ngữ riêng tên Raku.
Chạy Hello, world
Kiểm tra Perl đã được cài bằng perl -v. Trên Windows, Strawberry Perl là một bản phân phối phổ biến. Hãy bắt đầu mọi script bằng use strict; và use warnings;: chúng bắt lỗi gõ nhầm và mã không an toàn.
#!/usr/bin/env perl
use strict;
use warnings;
print "Hello, world!\n";perl hello.pl
# Hello, world!
perl -e 'print "Hello from a one-liner\n"'Câu lệnh kết thúc bằng dấu chấm phẩy. Chú thích bắt đầu bằng #. Chuỗi trong dấu nháy kép nội suy biến và các chuỗi thoát như \n; chuỗi trong dấu nháy đơn được giữ nguyên.
Biến: scalar, mảng và hash
Biến Perl bắt đầu bằng một sigil cho biết loại giá trị. Khai báo mỗi biến bằng my, để biến cục bộ trong khối bao quanh.
use strict;
use warnings;
my $name = "Perl"; # scalar: one value
my $year = 1987;
my @langs = ("Perl", "C", "sh"); # array: ordered list
my %port = (http => 80, https => 443); # hash: key-value pairs
print "$name since $year\n"; # Perl since 1987
print "First: $langs[0]\n"; # First: Perl (element is a scalar, so $)
print "Count: ", scalar(@langs), "\n"; # Count: 3
print "HTTPS: $port{https}\n"; # HTTPS: 443
print "Sum: ", "10" + 5, "\n"; # Sum: 15 (strings convert to numbers)
print "Join: " . "a" . "b" x 3, "\n"; # Join: abbb| Sigil | Loại | Ví dụ |
|---|---|---|
$ | scalar: một số, chuỗi hoặc tham chiếu | my $n = 42; |
@ | mảng: danh sách có thứ tự các scalar | my @list = (1, 2); |
% | hash: các cặp khóa-giá trị không có thứ tự | my %h = (a => 1); |
& | subroutine (hiếm khi viết như vậy) | &name |
Điều khiển luồng
Perl có if, elsif, else, unless, while, until, for và foreach. Một câu lệnh ngắn có thể theo sau bởi điều kiện, đọc như tiếng Anh. next nhảy sang lần lặp kế tiếp và last thoát khỏi vòng lặp.
use strict;
use warnings;
my $score = 72;
if ($score >= 90) {
print "A\n";
} elsif ($score >= 70) {
print "B\n"; # B
} else {
print "C\n";
}
print "passed\n" if $score >= 50; # statement modifier
print "not perfect\n" unless $score == 100;
for my $i (1 .. 3) {
print "i = $i\n";
}
my @names = ("ann", "bo");
foreach my $n (@names) {
next if $n eq "bo"; # skip to the next item
print ucfirst($n), "\n"; # Ann
}
my $k = 3;
while ($k > 0) { $k--; }Các giá trị sai là 0, "0", chuỗi rỗng "", danh sách rỗng và undef. Mọi thứ khác đều đúng.
Subroutine
Định nghĩa hàm bằng sub. Các đối số đến trong mảng đặc biệt @_, và dòng đầu thông thường sẽ sao chép chúng vào các biến có tên. Một subroutine có thể trả về một scalar hoặc một danh sách.
use strict;
use warnings;
sub add {
my ($x, $y) = @_; # arguments arrive in @_
return $x + $y;
}
sub greet {
my ($name, $greeting) = @_;
$greeting //= "Hello"; # default if undefined
return "$greeting, $name!";
}
sub stats {
my @nums = @_;
my $sum = 0;
$sum += $_ for @nums;
return ($sum, $sum / @nums); # return a list
}
print add(2, 3), "\n"; # 5
print greet("Ann"), "\n"; # Hello, Ann!
my ($total, $avg) = stats(4, 8, 6);
print "$total $avg\n"; # 18 6Perl hiện đại cũng hỗ trợ signature, như sub add($x, $y) { ... }, được bật bằng use v5.36; trở lên, đồng thời cũng bật strict và warnings.
Mảng, hash và tham chiếu
Mảng và hash đi kèm các hàm dựng sẵn mạnh như push, pop, shift, sort, map, grep, keys và exists. Dữ liệu lồng nhau dùng tham chiếu: [ ... ] tạo tham chiếu mảng và { ... } tạo tham chiếu hash, còn -> đi theo chúng.
use strict;
use warnings;
my @nums = (5, 3, 8, 1);
push @nums, 9; # add to the end
my $last = pop @nums; # remove from the end: 9
my @sorted = sort { $a <=> $b } @nums; # numeric sort
my @doubled = map { $_ * 2 } @sorted;
my @big = grep { $_ > 4 } @sorted;
print "@sorted | @doubled | @big\n"; # 1 3 5 8 | 2 6 10 16 | 5 8
my %age = (ann => 31, bo => 25);
$age{cy} = 40;
delete $age{bo};
for my $who (sort keys %age) {
print "$who is $age{$who}\n"; # ann is 31 / cy is 40
}
print "has ann\n" if exists $age{ann};
# references build nested data structures
my $user = { name => "Ann", langs => ["Perl", "SQL"] };
print "$user->{name} knows $user->{langs}[1]\n"; # Ann knows SQL
print scalar @{ $user->{langs} }, "\n"; # 2Trong khối sort, $a và $b là hai phần tử đang được so sánh. <=> so sánh theo số và cmp so sánh như chuỗi; sort @list thông thường sắp xếp như chuỗi, nên 10 đứng trước 9.
Biểu thức chính quy
Biểu thức chính quy được tích hợp vào cú pháp của Perl, và đó là tính năng đặc trưng của nó. =~ áp dụng phép khớp m/.../ hoặc phép thay thế s/.../.../. Các nhóm bắt được có sẵn dưới dạng $1, $2 và tiếp theo, còn các bộ điều chỉnh như g (toàn cục) và i (không phân biệt hoa thường) đứng sau dấu gạch chéo đóng.
use strict;
use warnings;
my $line = "2026-10-31 ERROR disk full on /dev/sda1";
if ($line =~ /^(\d{4})-(\d\d)-(\d\d)\s+(\w+)/) {
print "year=$1 level=$4\n"; # year=2026 level=ERROR
}
(my $masked = $line) =~ s/\d/#/g; # copy, then replace digits
print "$masked\n"; # ####-##-## ERROR disk full on /dev/sda#
my @words = split /\s+/, $line;
print scalar(@words), " words\n"; # 6 words
my %h = ("a=1, b=2, c=3" =~ /(\w)=(\d)/g); # pairs into a hash
print join(",", map { "$_$h{$_}" } sort keys %h), "\n"; # a1,b2,c3Dùng qr/.../ để lưu mẫu đã biên dịch vào một biến, và bộ điều chỉnh x để viết mẫu dài trên nhiều dòng kèm chú thích.
Xử lý lỗi
die phát sinh một ngoại lệ còn warn in cảnh báo ra đầu ra lỗi chuẩn. eval { ... } bắt ngoại lệ và đặt thông báo lỗi vào $@. Các lời gọi hệ thống như open trả về sai khi thất bại và đặt $! thành lỗi của hệ điều hành, vì vậy hãy kiểm tra chúng bằng or die.
use strict;
use warnings;
sub divide {
my ($x, $y) = @_;
die "division by zero\n" if $y == 0;
return $x / $y;
}
my $result = eval { divide(1, 0) };
if ($@) {
print "Caught: $@"; # Caught: division by zero
}
open(my $fh, "<", "missing.txt")
or print "Cannot open: $!\n"; # Cannot open: No such file or directoryThông báo die kết thúc bằng \n được in nguyên văn; nếu không có ký tự xuống dòng, Perl sẽ thêm tên tệp và số dòng. Từ Perl 5.34 còn có tính năng try/catch thử nghiệm, và các module như Try::Tiny được dùng rộng rãi.
Một chương trình hoàn chỉnh nhỏ: đếm mức độ log
Script này đọc log từ các tệp nêu trên dòng lệnh hoặc từ đầu vào chuẩn, đếm số dòng theo mức độ và in bản tóm tắt đã sắp xếp. Nó minh họa toán tử kim cương <>, biểu thức chính quy, hash và printf.
#!/usr/bin/env perl
# logstat.pl: count log levels in a file or standard input
use strict;
use warnings;
my %count;
my $lines = 0;
while (my $line = <>) { # reads files named on the command line, or STDIN
chomp $line;
$lines++;
next unless $line =~ /\b(INFO|WARN|ERROR)\b/;
$count{$1}++;
}
printf "%d lines read\n", $lines;
for my $level (sort { $count{$b} <=> $count{$a} || $a cmp $b } keys %count) {
printf "%-5s %3d\n", $level, $count{$level};
}perl logstat.pl app.log
# 120 lines read
# INFO 97
# WARN 18
# ERROR 5Học tiếp ở đâu
- perlintro và các hướng dẫn khác tại perldoc.perl.org, cũng dùng được ngoại tuyến bằng
perldoc perlintro. - Learning Perl và Modern Perl, hai cuốn sách nổi tiếng cho người mới.
- MetaCPAN, giao diện tìm kiếm các module CPAN.
- perlre và perlretut cho tài liệu tham chiếu đầy đủ về biểu thức chính quy.
Câu hỏi thường gặp
Perl còn được dùng không?
Có. Perl được cài sẵn trên hầu hết hệ thống giống Unix và vẫn phổ biến trong quản trị hệ thống, xử lý văn bản, tin sinh học và các hệ thống nghiệp vụ chạy lâu năm, dù ít dự án web mới bắt đầu bằng Perl.
Perl và Raku khác nhau thế nào?
Raku khởi đầu là Perl 6 nhưng trở thành một ngôn ngữ riêng với thiết kế khác. Perl 5 tiếp tục được phát triển độc lập, và tên Perl chỉ ngôn ngữ này.
Vì sao biến Perl bắt đầu bằng $, @ và %?
Sigil cho biết bạn nhận được loại giá trị nào: $ cho một scalar đơn, @ cho danh sách và % cho hash. Vì thế một phần tử của @items được viết là $items[0].
chomp làm gì trong Perl?
chomp xóa ký tự xuống dòng ở cuối chuỗi, thứ bạn thường cần sau khi đọc một dòng từ tệp hoặc bàn phím.
Perl có tốt cho biểu thức chính quy không?
Có. Biểu thức chính quy là một phần của cú pháp lõi của Perl, và PCRE, thư viện regex được nhiều công cụ và ngôn ngữ khác dùng, được đặt tên theo kiểu regex của Perl.