perl_5321

118
Giáo Trình Ngôn ngữ lập trình Perl 1

Transcript of perl_5321

Page 1: perl_5321

Giáo Trình

Ngôn ngữ lập trình Perl

1

Page 2: perl_5321

MỤC LỤC

Trang

Chương I: Cú pháp, tập lệnh, các kiểu dữ liệu

1. Các phần tử cơ bản của ngôn ngữ Perl ...................................................................................... 8

2. Các kiểu dữ liệu cơ sở .................................................................................................................9

3. Các câu lệnh điều khiển ..............................................................................................................15

Chương II: Vào / ra dữ liệu

1. Nhập dữ liệu vào..........................................................................................................................24

2. Xuất dữ liệu ra ............................................................................................................................ 25

Chương III: Mảng, danh sách và hash

1. Danh sách (List)..........................................................................................................................30

2. Mảng...........................................................................................................................................30

3. Mảng liên kết (Hash)..................................................................................................................34

Chương IV: Chương trình con

1.Khái niệm.......................................................................................................................................37

2. Cách gọi hàm................................................................................................................................37

3. Trả lại giá trị cho hàm...................................................................................................................38

4. Biến cục bộ trong hàm..................................................................................................................38

5. Truyền tham số cho hàm...............................................................................................................39

6. Hàm đệ qui....................................................................................................................................40

7. Chỉ định thứ tự sắp xếp..................................................................................................................41

8. Một số hàm đặc biệt trong Perl.....................................................................................................42

Chương V: Tệp (file)

1. Khái niệm về tệp ..........................................................................................................................44

2. Các thao tác...................................................................................................................................44

3. Kiểm tra tệp...................................................................................................................................46

2

Page 3: perl_5321

4. Một số hàm xử lí tệp.....................................................................................................................49

5. Một số hàm cho thư mục(Directory) ............................................................................................51

Chương VI: Xâu và xử lý văn bản trong Perl

1. Toán tử đối sánh...........................................................................................................................53

2. Các kí tự đặc biệt trong khuôn mẫu.............................................................................................53

3. Tuỳ chọn khuôn mẫu đối sánh......................................................................................................57

4. Toán tử thay thế............................................................................................................................58

5. Toán tử truyền đạt.........................................................................................................................59

6. Khuôn mẫu đối sánh mở rộng...................................................................................................... 59

7. Các Hàm split() và join()...............................................................................................................60

Index A - List mã nguồn bài tập tần suất từ......................................................................................62

Index B - Nhúng Perl vào trong C và cấp bộ nhớ động cho Perl .....................................................70

Index C - Vài nét về PHP trên cơ sở Perl...........................................................................................74

Index D - Tài liệu tham khảo..............................................................................................................76

CHƯƠNG 1 - VÀI NÉT VỀ NGÔN NGỮ LẬP TRÌNH PERL

1.Lịch sử của PerlNgày 18/10/1987 Larry Wall tác giả của ngôn ngữ này lần đầu tiên đưa Perl vào sử dụng tại nhóm usenet comp.sources . Ngôn ngữ này phát sinh từ C và chịu ảnh hưởng bởi các ngôn ngưx khác như BASIC, awk, sed và UNIX Shell. Perl là viết tắt của Practical-Extraction and Report- Language. Mục đích ban đầu là tạo ra các bản báo cáo nhanh chóng và dẽ dàng.

2. Các đặc trưng của PerlCác ngôn ngữ và công cụ lập trình hiện nay rất nhiều, vì thế rất nên biết rõ điểm mạnh và điểm yếu riêng của từng ngôn ngữ để có thể tùy chọn với những ứng dụng cụ thể. Ngoài ra một trong những mục đích củabản báo cáo này là viết về Perl cho cả các đối tượng đã có nền tảng là C hay Shell. Cho nên cần phải phân tích các đặc trưng của Perl.

2.1 Perl là một trình thông dịch

Chương trình Perl được dịch đọc trọn vẹn và lưu trữ ở hình thức trung gian trước khi chương trình này được thực hiện. Tuy nhiên tốc độ xử lý sê không bằng các ngôn ngữ biên dịch như C hay C++

2.2 Xử lý text rất mạnh

Do có nhiều toán tử cũng như hàm để hỗ trợ riêng cho xử lý text nên Perl khác biệt với các ngôn ngữ khác là có tính chất xử lý text rất mạnh, có thể xử lý dễ dàng những tác vụ giống như C hoặc UNIX shell thường làm trong việc viết một Script nhưng có thể ngắn gọn và đơn giản hơn.

3

Page 4: perl_5321

2.3 Perl có cú pháp giống C và Shell và có thể tích hợp với C

Perl và C đều là những ngôn ngữ lập trình phổ biến. Mỗi ngôn ngữ có những điểm mạnh và điểm yếu riêng. C là một ngôn ngữ lập trình vạn năng, có tính thích nghi khả chuyển cao, cho phép can thiệp sâu vào hệ thống. Hơn nữa tốc độ biên dịch cũng như tốc độ chạy của các ứng dụng viết bằng C khá nhanh và ổn định. Trong khi Perl mặc dù chạy chậm hơn,nhưng lại rất mạnh ở xử lý văn bản, điều mà ngôn ngữ C không hỗ trợ nhiều. Hơn nữa 80% người bắt đầu học Perl đã từng làm quen với C hoặc C++. Cho nên càng dễ học Perl. Perl có thể tận dụng tới các thư viện của C và ngược lại(trong một số điều kiện nhất định)Perl từ version 5.0 có thể tích hợp khá dễ dàng với các ứng dụng viết bằng C hoặc C++.

Đối với Shell, ngôn ngũ script cơ bản nhất trong UNIX, Perl rất giống ngôn ngữ này cả trong cú pháp lẫn hàm. Tuy nhiên có 1 vài điểm khác biệt đáng quan tâm. Một trong những điểm khác biệt lớn nhất giữa cách hoạt động của Perl và Shell là Perl không chỉ là ngôn ngữ phiên dịch. Chương trình Perl được dịch đọc trọn vẹn và lưu trữ ở hình thức trung gian trước khi chương trình này được thực hiện. Chương trình Shell được đọc và thi hành mỗi lần 1 lệnh. Điều này mang lại 2 lợi ích cho chương trình viết bằng Perl so với chương trình viết bằng Shell:

+ Đầu tiên là chương trình Perl chạy nhanh hơn nhiều so với chương trình Shell. Đó là do bộ biên dịch Perl kiểm tra cú pháp gỡ chú giải trước khi bắt đầu thực hiện mã

+ Thứ hai, bạn không phải lo lắng về chương trình Shell lớn làm ngưng nửa chừng việc thực thi do lỗi cú pháp, vì tất cả mã được phân tích trước khi bắt đầu làm việc

Perl còn có tính năng cho phép bạn lập trình trên một máy rồi dời nó đến 1 nền khác mà không cần phải thay đổi nào.

2.4 Perl phát huy sức mạnh tối đa trên nền UNIX

Các nhà quản trị hệ thống và phát triển ứng dụng UNIX thường phải dùng tới một số ngôn ngữu lập trình khác nhau để hoàn tất các tác vụ cần thực hiện. Ví dụ như để xử lý một file trong UNIX ta phải viết 1 đoạn Shell script sử dụng sh hoặc awk hay grep, và để biên tập file đó cần dùng đến shed. Để can thiệp sâu vào hệ thống UNIX, ta lại phải dùng nhiều đến C. Chính vì thế nảy sinh nhu cầu cần sử dụng một ngôn ngữ vừa dễ viết, dễ phát triển, lại vừa xử lý một cách có hiệu quả nhiều tác vụ. rong khi đó Perl lại là một trong những ngôn ngữ mạnh nhất trên UNIX. Nó chứa toán tử cung cấp hầu hết các hàm mà người lập trình muốn thực hiện trong môi trường UNIX. Chính vì thế, bên cạnh C, Perl là một ngôn ngữ được cộng đồng Phần mềm mã nguồn mở sử dụng rộng rãi trên thế giới.Những người biết rõ ngôn ngữ lập trình awk sẽ không ngạc nhiên là Perl mượn nhiều đặc sắc của awk. Perl cũng bao gồm 1 vài đặc tính hay nhất của C, sed, và ngôn ngữ Shell trong UNIX như là bash và tcsh.

2.5 . Perl có thể chạy trên các môi trường khác nhau- UNIX PERL chạy trên môi trường Unix.- PERL FOR WINDOWS NT chạy trên môi trường Windows NT. -WIN PERL chạy trên môi trường Windows 95/ Windows 98. 2.6 Perl cũng là một ngôn ngữ đa nhiệm

Perl được tối ưu hóa cho xử lý văn bản . Trong những phiên bản hiện thời, Perl cũng bao gồm nhiều tính năng bổ sung như lập trình socket, tích hợp với C. Từ phiên bản 5.0, có thêm hướng đối tượng. Mặc dù, ta hay nghe nói Perl là để lập trình cho web, nhưng trên thực tế không phải như vậy. Perl còn là một ngôn ngữ lập trình hệ thống khá mạnh trong Unix

2.6 Perl là một ngôn ngữ rất thích hợp với CGI và Socket

2.6.1 Các CGI script

4

Page 5: perl_5321

Perl là một trong những ngôn ngữ thông dụng nhất để tạo ra những ứng dụng CGI(Common Gateway Interface). Có hàng nghìn ví dụ lập trình CGI động trong Perl. Perl có thể được sử dụng để tạo ra những trang Web động

Một trong những ứng dụng phổ biến nhất của Perl trên Internet là xử lý mẫu nhập vào, bởi vì hầu hết đó là văn bản

2.6.2 Lập trình Socket

Perl có khả năng tới đọc/ghi các TCP/IP socket. Chẳng hạn, Perl có thể dùng để viết một chương trình tự động kiểm tra địa chỉ IP để xác minh tính hợp lệ của 1 trang Web. Điều này đặc biệt hữu ích trong việc cập nhật các trang Web

2.6.3 Xử lý email

Các chương trình Perl được sử dụng để lọc email dựa vào địa chỉ hoặc nội dung, tự động sắp xếp danh sách email(mailling lists). Một trong số web mail nổi tiếng nhất là http://www.hotmail.com với hầu hết các trang có dạng *.cgi

2.7 Perl có những tiện ích hỗ trợ việc gỡ lỗi

Trình thông dịch Perl có sẵn một trình gỡ rối, có thể giúp giảm bớt thời gian dùng đến gỡ lỗi những ứng dụng. Trình gỡ rối được kích hoạt thường xuyên nhờ sử dụng tùy chọn - d khi biên dịch. Ngoài ra, - w cung cấp một tập hợp đầy đủ những cảnh báo

2.8 Perl là một ngôn ngữ lập trình mã nguồn mởPerl được phân phối theo phép công cộng GNUVì thế ta sẽ được nhiều sự hỗ trợ . Chẳng hạn có thể liên hệ trực tiếp với Larry hoặc nhóm hỗ trợ Perl trực tuyến toàn thế giới, liên lạc thông qua nhóm tin Usenet comp.lang.perl. hoặc gửi yêu cầu tới [email protected]. Cấu trúc cơ bản của 1 chương trình Perl

Ta hãy nhìn vào một chương trình rất đơn giản nhưng thể hiện được những yếu tố căn bản nhất của Perl. Đó là chương trình “Hello.pl”:

Dòng đầu tiên là giống như một câu nói rằng đây là chương trình Perl. Nó cũng là lời chú thích cho Perl. Bởi vì chú thích của Perl giống như chú thích của Shell. Bất kì cái gì nằm giữa một dấu thăng (#) tới cuối dòng đều là một chú thích. Không có khái niệm về chú thích trên nhiều dòng như C.

Dòng thứ hai là toàn bộ phần thực hiện được của chương trình này. Tại đây chúng ta thấy câu lệnh print. Từ khoá print bắt đầu chương trình, và nó có một đối, một xâu văn bản kiểu như C. Bên trong xâu này, tổ hợp kí tự \n biểu thị cho kí tự dòng mới; hệt như trong C. Câu lệnh print được kết thúc bởi dấu chấm phẩy (;). Giống như C, tất cả các câu lệnh đơn giản đều kết thúc bằng chấm phẩy* . Nhưng chương trình Perl bao gồm tất cả các câu lệnh perl về tệp được lấy tổ hợp chung như một trình lớn cần thực hiện. Không có khái niệm về trình “chính” main như trong C.(điều này giống như trong Shell)

Khi gọi chương trình này, phần lõi sẽ gọi bộ thông dịch Perl, phân tích câu toàn bộ chương trình (hai dòng, kể cả dòng chú thích đầu tiên) và rồi thực hiện dạng đã dịch. Thao tác đầu tiên và duy nhất là thực hiện toán tử print, điều này gửi đối của nó ra lối ra. Sau khi chương trình đã hoàn tất, thì tiến trình Perl ra, cho lại một mã ra thành công cho lớp vỏ.

*

5

Page 6: perl_5321

CHƯƠNG 1: CÚ PHÁP, TẬP LỆNH, CÁC KIỂU DỮ LIỆU

Phần 1: Các phần tử cơ bản của ngôn ngữ Perl

1. Tập kí tự

26 chữ cái hoa A, B, C, ...., Z

26 chữ cái thường a, b, c, ...., z

10 chữ số 0, 1, ...., 9

các kí hiệu toán học + - * / = ...

các dấu ngăn cách . , : ; dấu cách

các kí tự khác _ ? < > [ ] { } ~ ! @ # $ % ^ & * ( ) ...

Các kí hiệu khác có thể dùng tong xâu hoặc trong chú thích

2. Từ khoá

Dưới đây liệt kê một số từ khoá thông dụng của Perl :

if else elsif while next sub print printf do select whileuntil for foreach unless die sort my binmode

3. Tên (định danh – identifier)

Tên là một khái niệm rất quan trọng, nó dùng để xác định các đại lượng khác nhau trong một chương trình. Chúng ta có tên hằng, tên biến, tên mảng, tên hàm, tên tệp, tên cấu trúc, tên nhãn,...

Tên trong Perl được đặt theo quy tắc sau : là một dãy các kí tự liền nhau gồm các chữ cái và số và dấu gạch dưới _, tên không được bắt đầu bằng chứ số hay dấu gạch dưới, không được chứa các kí tự đặc biệt.

Ví dụ:

Tên đúng : a1 a_2 xau

Tên sai :

1tu sai vì bắt đầu bằng chữ số

m&n sai vì có chứa kí tự &

hai tu sai vì sử dụng dấu cách

6

Page 7: perl_5321

if sai vì trùng với từ khoá

Tuy nhiên có hai kiểu tên đặc biệt trong Perl gắn liên với hai kiểu dữ liệu là biến vô hướng và mảng

Tên biến vô hướng được bắt đầu bằng $

Tên mảng được bắt đầu bằng @

Chú ý :Tên trong Perl có độ dài tuỳ ý và có phân biệt chữ hoa với chữ thường. Vì vậy tên

là Pi sẽ khác tên là PI và pI.

4.Cách ghi lời giải thích

Khi lập trình cần có thêm lời giải thích ghi chú để làm cho chương trình dễ đọc, dễ hiểu hơn mà không gây ảnh hưởng đến sự làm việc của chương trình. Các lời giải thích trong Perl được bắt đầu bằng kí tự # và tất cả những gì nằm sau # cho đến cuối dòng đều là lời giải thích.Mọi thứ đằng sau # khi dịch chương trình sẽ bị bỏ qua:

ví dụ:

$a=<STDIN>; #Nhap vao gia tri a

print "So cua nhap va la : $a\n"; # In so vua nhap ra man hinh

5.Câu lệnh và dấu chấm câu

Một chương trình gồm nhiều câu lệnh, mỗi câu lệnh thực hiện một công việc nào đó. Các câu lệnh phải được ngăn cách nhau bởi dấu ; .

6.Một số chương trình đơn giản viết bằng Perl

Ví dụ 1: In ra màn hình dòng chữ Learning Perl is very good

#!/usr/bin/perl

print “Learning Perl is very good”;

Ví dụ 2:In ra lời chào

#!/usr/bin/perl

print “Ban ten la gi ?”;

$a=<STDIN>;

chomp($a);

print “\nChao ban $a”;

7

Page 8: perl_5321

Phần II: Các kiểu dữ liệu cơ sở

1. Các kiểu dữ liệu

1.1 Biến và hằng .

Dữ liệu chứa trong máy tính có thể là biến hoặc hằng :

Biến là đại lượng có thể thay đổi được giá trị

Hằng là đại lượng có giá trị không thay đổi

1.1.1 Hằng kí hiệu

Hằng kí hiệu là cách thức biểu diễn dữ liệu trong mã chương gốc của chương trình như cái vào cho trình biên dịch Perl.

Hằng kí hiệu động :giống như hằng dấu phẩy động trong C.

Ví dụ :1.25     # một và 1/4

7.25e45  # 7,25 x 1045 (một số dương lớn)-6.5e24  # -6,5 x 1024 (một số âm lớn)-12e-24  # -12 x 10-24 (một số âm rất nhỏ)-1.2E-23 # tương tự như số ở trên: -1,2 x 10-23

Hằng kí hiệu nguyên :

Các hằng kí hiệu nguyên cũng được ghi trực tiếp.

Ví dụ :1215-20043485

Không nên đứng đầu bắng chữ số 0 bởi vì trong Perl hỗ trợ cho hằng hệ cơ số tám và hệ cơ số mười đều được bắt đầu bằng chữ số 0.

Ví dụ :0377   # 377 hệ tỏm = 255 trong hệ thập phõn-0xff # õm FF hệ mười = -255 trong hệ thập phõn

1.2. Kiểu số nguyên

Kiểu nguyên trong Perl được lưu trữ trong máy dưới dạng số thực dấu chấm động. Do đó kiểu nguyên trong Perl có dải giá trị rất lớn, bằng với dải giá trị thực dấu chấm động mà máy có thể xử lý được.

Các hằng kí hiệu nguyên được viết ra bằng dãy các chữ số 0, 1, .. 9 và kí tự đầu có thể là dấu + hoặc dấu – hay không có dấu

Ví dụ :

$x = 987

$y = -123

8

Page 9: perl_5321

$z = 12345678987766565 một số rất lớn

Cũng như C, Perl cho phép bạn biẻu diễn hằng nguyên dạng hệ 8 hay 16. Hệ 8 có chữ số 0 ở đầu, còn hằng nguyên hệ 16 bắt đầu bằng 0x hoặc 0X

hệ 10 hệ 8 hệ 16

198 0306 0xC6

1.3. Kiểu số thực

Có dải giá trị khoảng từ E-309 đến E+308. Tuy nhiên máy chỉ có thể xử lý với khoảng 16 hay 17 chữ số có nghĩa, cho nên khi thao tác với số qua lớn có thể chúng ta sẽ không nhận được giá trị như mong muốn.

Ví dụ :

9.01e+21 + 0.01 - 9.01e+21

Sẽ cho ta giá trị 0 bởi vì trong quá trình cộng 9.01e+21 + 0.01 máy bỏ bớt một số chữ số đi nên kết quả nhận được là 9.01e+21

Cách biểu diễn hằng thực cũng như trong C dạng bình thường và dạng có phần số mũ.

1.23

4.56e-10

1.4. Kiểu xâu.

Xâu là một dãy các kí tự.Mỗi kí tự đều là một giá trị 8 bit

Có hai loại xâu trong Perl :

1.4.1. Xâu nháy kép

Là một dãy các kí tự bất kì được đặt trong hai dấu nháy kép.

Ví dụ :

“Day la mot xau”

“Day cung_la xau?”

Trong xâu nháy kép có thể có dấu sổ chéo ( \ ) là kí tự để xác định kí tự điều khiển nào đó. Bảng sau đây sẽ liệt kê một số kí tự điều khiển

Kí tự Giải thích

\a Đổ chuông, BELL

\b Xoá trái

\cn Kí tự Ctrl + n

9

Page 10: perl_5321

\e Escape

\E Kết thúc \L, \U, \Q

\f Báo hết trang

\l Chuyển kí tự tiếp theo thành chữ thường

\L Tất cả các kí tự tiếp theo chuyên thành chữ thường

\n Chuyển sang dòng mới

\r Về đầu dòng

\t Tab

\u Chuyển kí tự tiếp theo thành chữ hoa

\U Tất cả các kí tự tiếp theo chuyên thành chữ hoa

\007 Kí tự ASCII ở hệ 8 (007 = bíp)

\” Kí tự “

\\ Kí tự \

\v Nhẩy cách đứng

Ví dụ :

Chúng ta muốn có xâu có dấu ngoặc kép bên trong thĩ xâu đầy đủ là

“ dau \” ngoac kep\” ”

“ chu \U hoa ” -> chuyển xâu thành “ chu HOA ”

Ngoài ra bạn cũng có thể sử dụng cách viết sau để biểu diễn một kí tự nào đó trong bảng mã ASCII :

\xnn với nn là giá trị số viết dưới dang hệ 16 của kí tự trong bảng mã ASCII.

\xnnn với nnn là giá trị số viết dưới dang hệ 8 của kí tự trong bảng mã ASCII.

Ví dụ :

\377 biểu diễn kí tự thứ 7 hay đổ chuông (bell)

\xff biểu diễn kí tự thứ 255 hay EOF

10

Page 11: perl_5321

1.4.2. Xâu nháy đơn

Perl cũng cho phép bạn sử dụng xâu trong hai dấu nháy đơn.

ví dụ : ‘day la xau nhay don’

Khác với xâu nháy kép, xâu nháy đơn có thể được đặt trên nhiều dòng và các kí tự điều khiển sẽ không có tác dụng ngoại trừ hai trường hợp dấu ‘ và dấu \..

Ví dụ :

Xâu nháy đơn Xâu nháy kép

‘ho ten

nguyen van a’ “ho ten\nnguyen van a”

‘tab \t’ “tab \t”

‘don\’t’ “don’t”

“so cheo : \\’ “so cheo : \”

Một sự khác biệt nữa giữa xâu nháy đơn và xâu nháy kép là các biến nếu được đặt trong xâu nháy kép thì sẽ cho giá trị của biến, càon xâu nháy đơn thì không.

1.4.3. Một số phép toán dối với xâu

a. Lặp lại xâu

Dùng toán tử x

Ví dụ $mau = “xanh” x 2;

hay $mau x= “xanh”; # đều cho ta $mau = “xanhxanh”

b. Nối xâu.

Dùng toán tử .

Ví dụ $hoten = “Nguyen” . “ An”; # cho ta $hoten = “Nguyen An”

c. Một số hàm cho xâu

index (s1, s2) trong đó s1, s2 là biểu thức xâu kí tự. Hàm này cho ta vị trí đầu tiên của xâu s2 gặp trong xâu s1

rindex (s1, s2) hàm này tương tự như hàm index, nhưng nơi bắt đầu tìm kiếm là cuối xâu s1.

length(st) hàm này cho ta độ dài của xâu kí tự st.

pos(st) chỉ ra vị trí của khuôn mẫu được đối sánh trong xâu.

substr(st, pos, len) trả lại giá trị là một xâu gồm len kí tựđược tách ra từ xâu st, bắt đầu từ vị trí pos trong xâu.

lc(st) chuyển đổi tất cả các kí tự trong xâu st ra chữ thường

uc(st) chuyển đổi tất cả các kí tự trong xâu st ra chữ hoa

11

Page 12: perl_5321

lcfirst(st) chuyển đổi kí tự đầu tiên của xâu st ra chữ thường

ucfirst(st) chuyển đổi kí tự đầu tiên của xâu st ra chữ hoa

quotemeta(st) trả lại giá trị là xâu kí tự được thêm dấu \ vào trước những kí tự không phải là từ trong xâu st

join(joinstr, list) trả lại giá trị là một xâu được ghép nối bởi các phần tử trong danh sách list và giữa hai phần tử trong xâu ghép nối là xâu joinstr

@list = ("Day", "la", "vi", "du.");

$str = join (" ", @list); #Lệnh gán này cho $str = “Day la vi du.”

II. Biến, biểu thức và lệnh gán

1. Biến

Biến là đại lượng có thể thay đổi được giá trị

Khái niệm biến trong Perl gắn liền với khái niện biến vô hướng. Một biến vô hướng thì giữ một giá trị vô hướng riêng : có thể là một dòng dữ liệu, một đoạn văn bản, hay một số. Giá trị được lưu giữ trong biến vô hướng được gọi là giá trị vô hướng.

Quy tắc đặt tên biến vô hướng : Gồm kí tự $ ở đầu tên, tiếp sau là chữ, chữ số hay dấu _ (phần sau kí tự $ tuân theo quy tắc đặt tên đã giới thiệu trong phần trước)

Ví dụ : $x

$delta

$ki_tu

2. Biểu thức

Biểu thức là một sự kết hợp giữa các phép toán và các toán hạng cùng các dấu ngoặc đơn để diễn đạt một công thức toán học nào đó.

Toán hạng là một đại lượng nào đó, có thể là hằng, biến hay hàm.

Các phép toán được dùng trong ngôn ngữ Perl

a. Số học + - * / %(lấy phần dư) **(mũ)

Ví dụ 5 % 3 = 2

10.3 % 3.4 = 1 ( số thực sẽ được chuyển thành số nguyên trước khi thực hiện phép toán)

2**3 = 8

Chú ý :

Perl không phép nâng luỹ thừa số âm hay số luỹ thừa lẻ (không ngyên)

Trong lập trình bạn cũng phải cẩn thận tránh tạo ra số quá lớn.

b. So sánh

Có hai loại phép toán so sánh trong Perl:

12

Page 13: perl_5321

- So sánh số học.

- So sánh xâu.

Bảng 1.1 : Các phép toán so sánh số học

Phép toán ý nghĩa

< Nhỏ hơn

> Lớn hơn

== Bằng

<= Nhỏ hơn hoặc bằng

>= Lớn hơn hoặc bằng

!= Khác nhau

<=> Cho giá trị -1(<) 0(==) 1(>)

Bảng 1.2 : Các phép toán so sánh xâu

Phép toán ý nghĩa

lt Nhỏ hơn

gt Lớn hơn

eq Bằng

le Nhỏ hơn hoặc bằng

ge Lớn hơn hoặc bằng

ne Khác nhau

cmp Cho giá trị -1(<) 0(==) 1(>)

c. Các phép toán logic

Cách biểu diễn phép toán logic trong Perl dưới dạng kí hiệu và chữ như sau là như nhau:

13

Page 14: perl_5321

&& And

|| or

! not

d. Các phép toán bit

& AND bit

| OR bit

^ XOR bit

~ NOT bit

<< dịch trái bit

>> dịch phải bit

Ví dụ

01111100 biểu diễn số 124

01100011 biểu diễn số 99

sau khi thực hiện phép XOR bit |

kết quả 00011111

dịch trái số 99

kết quả 11000110

3. Lệnh gán

Cú pháp:

<biến> = <biểu thức>

biểu thức cũng có thể là biểu thức gán:

$a = $b = ($c =10) * 5

cũng như C , Perl cho phép thu gọn biểu thức gán :

<biến> = <biến> <phép toán> <toán hạng>

14

Page 15: perl_5321

<biến> <phép toán>= <toán hạng>

$x = $x + 5 có thể viết thành $x += 5

...

các phép gán thường dùng là += -= *= /= %= **= &= |= ^=

Biểu thức theo điều kiện :

<biểu thức 1> ? <biểu thức 2> : <biểu thức 3>

Gán theo điều kiện

<biến> = <biểu thức 1> ? <biểu thức 2> : <biểu thức 3>

Nếu <biểu thức 1> đúng(=1) thì <biến> sẽ lấy giá trị của <biểu thức 2>, trường hợp ngược lại <biến> sẽ lấy giá trị của <biểu thức 3>

Biểu thức theo điều kiên trong Perl có thể nằm ở bên trái phép gán

<biểu thức 1> ? <biến 1> : <biến 2> = <biểu thức 2>

Nếu <biểu thức 1> đúng(=1) thì <biến 1> sẽ lấy giá trị của <biểu thức 2>, trường hợp ngược lại <biến 2> sẽ lấy giá trị của <biểu thức 2>

ví dụ :

$a=2>3 ? 6 : 9 ;

kết quả biến $a = 9 ;

4. Tăng giảm một đơn vị

Cú pháp:

<biến> ++ ++<biến>

<biến> -- -- <biến>

Sự khác nhau giữa dạng tiền tố và hậu tố là trong dạng tiền tố giá trị biến sẽ được tăng trước khi gán, còn dạng hậu tố thì biến được tăng sau khi gán.

15

Page 16: perl_5321

Trong Perl phép tăng (chỉ có phép tăng) một đơn vị còn được áp dụng cho cả xâu nếu xâu chỉ gồm các chữ cái và chữ số.

Ví dụ $xau = “abc”;

$xau++; # Cho ta $xau = “abd”

$xau = “abz”;

$xau++; #Cho ta $xau = “aca”

5. Thứ tự ưu tiên các phép toán

Bảng 1.3 Thứ tự ưu tiên các phép toán

Phép toán Chiều tính toán

++, -- L R

-, ~, ! R L

** R L

=~, !~ L R

*, /, %, x L R

+, -, . L R

<<, >> L R

-e, -r, etc.

<, <=, >, >=, lt, le, gt, ge L R

==, !=, <=>, eq, ne, cmp L R

& L R

|, ^ L R

16

Page 17: perl_5321

&& L R

|| L R

.. L R

? and : R L

=, +=, -=, *=, R L

các phép toán khác

, L R

not L R

and L R

or, xor L R

Phần III: Các câu lệnh điều khiển

1. Lệnh đơn, lệnh ghép

2. Lệnh rẽ nhánh: if, if…else, if…elsif

3. Lệnh lặp: while, for, foreach…

4. Các toán tử last,next,...

5. Lệnh goto

1. Lệnh đơn, lệnh ghép:

Lệnh đơn: một lệnh hoặc lời gọi hàm kết thúc bởi dấu ;

Ví dụ:

$a = 1;

print “Hello, World!\n”;

Lệnh ghép: dãy các lệnh được đặt trong 1 khối bắt đầu bởi { và kết thúc bởi }. Lệnh ghép được dùng trong cấu trúc lệnh mà cú pháp đòi hỏi như một lệnh độc lập (trong if, for, while,…)

(Tương tự như trong C)

2. Lệnh lựa chọn theo điều kiện if :

17

Page 18: perl_5321

Mẫu lệnh 1 :

If (<biểu thức điều kiện>)

{

<Lệnh 1>;

}

<Lệnh tiếp>;

Mẫu lệnh 2:

- If (<biểu thức điều kiện>)

{

<Lệnh 1>;

}

else

{

<Lệnh 2>;

}

<Lệnh tiếp>;

Lưu ý:

Dấu ngoặc múc { và } ở đây là cần thiết (cho dù bạn chỉ có một lệnh trong phần if hoặc else), nếu bạn thiếu thỡ Perl sẽ bỏo lỗi cỳ phỏp.

<Lệnh 1>, <lệnh 2> có thể là lệnh ghép

else đi theo if gần nhất

Điều kiện là biểu thức số; kiểm tra với 0

Ví dụ:

18

Page 19: perl_5321

Kết quả chạy chươngtrình:

- Nếu chỉ quan tâm đến các trường hợp khi biểu thức xác định là sai, có thể sử dụng lệnh điều khiển unless để tránh có một câu lệnh if…else.

Cú pháp câu lệnh unless:

unless (<biểu thức điều kiện>)

{

<Lệnh 1>;

}

<Lệnh tiếp>;

unless (<biểu thức điều kiện>)

{

<Lệnh 1>;

}

else

{

<Lệnh 2>;

}

<Lệnh tiếp>;

Ví dụ:

19

Page 20: perl_5321

Kết quả chạy chươngtrình:

Khi biểu thức điều kiện là sai, lệnh 1 sẽ được thực hiện. Trái lại, khi biểu thức điều kiện là đúng, lệnh 2 sẽ được thực hiện.

- Câu lệnh elsif:

Cú pháp:

if (<biểu thức điều kiện 1>)

{

<Lệnh 1>;

}

elsif (<biểu thức điều kiện 2>)

{

<Lệnh 2>;

}

else

{

<Lệnh 3>;

}

<Lệnh tiếp>;

3. Lệnh while:

- Cú pháp:

while (<biểu thức điều kiện>)

20

Page 21: perl_5321

{

<Lệnh>;

}

<Lệnh tiếp>;

- Nói chung: <Lệnh> phải làm cho biểu thức điều kiện trở thành 0, hoặc là lệnh ghép có chứa lệnh dừng vòng lặp (last,… )

Ví dụ:

Kết quả chạy chươngtrình:

4. Lệnh until:

Cú pháp:

until (<biểu thức điều kiện>)

{

<Lệnh>;

}

<Lệnh tiếp>;

Câu lệnh until ngược với câu lệnh while, <lệnh> chỉ được thực hiện khi biểu thức điều kiện là sai.

21

Page 22: perl_5321

Ví dụ:

Kết quả chạy chương trình:

5. Lệnh do…while, do…until

Cú pháp:

do

{

<Lệnh>;

}

while (<biểu thức điều kiện>)

do

{

<Lệnh>;

}

until (<biểu thức điều kiện>)

- Lưu ý:

<Lệnh> được thực thi ít nhất một lần, bất kể biểu thức điều kiện được xác định như thế nào.

22

Page 23: perl_5321

ở câu lệnh do…while, <lệnh> được lặp lại khi biểu thức điều kiện là đúng. Trái lại, ở câu lệnh do…until, <lệnh> được lặp lại khi biểu thức điều kiện là sai.

Ví dụ:

Kết quả chạy chương trình:

6. Lệnh for:

- Cú pháp:

for ([biểu thức 1];[biểu thức điều kiện];[biểu thức 2])

{

<Lệnh>;

}

<Lệnh tiếp>;

Nói chung phải có chế để for kết thúc.

1 khuông có thể có hơn 1 biểu thức

Ví dụ:

23

Page 24: perl_5321

Kết quả chạy chương trình:

7. Lệnh foreach:

- Cú pháp:

foreach <[biến](biến mảng)>

{

<Lệnh>;

}

<Lệnh tiếp>;

- Lưu ý:

Biến mảng (Array variable): Dãy dữ liệu cùng kiểu, đặt dưới tên chung và lưu ở bộ nhớ trong, có thể nhiều chiều. Biến mảng được biểu thị bằng ký tự @ đầu tiên.

Giá trị của biến vô hướng được gán trong vòng lặp foreach không có hiệu lực bên ngoài vòng lặp.

Ví dụ:

Kết quả chạy chương trình:

24

Page 25: perl_5321

8. Lệnh đơn dòng (single line):

Cú pháp:

<Lệnh> <[if][while][until][unless]> (<biểu thức điều kiện>);

- Các câu lệnh điều kiện đơn dòng được sử dụng khi không cần nhiều câu lệnh bên trong 1 khối lệnh.

Ví dụ:

Kết quả sau khi chạy chương trình:

9. Lệnh next, last và redo:

Dùng trong thân vòng lặp (là lệnh ghép) để dừng lặp, chuyển sang vòng lặp mới hoặc lặp lại một lần vòng lặp.

9.1 Toán tử last

Toán tử last tương đương câu lệnh Break của C : Dừng lặp, ra khỏi lệnh lặp và thực hiện <lệnh tiếp> đi sau lệnh lặp hiện tại.

ví dụ :

$a=20; while(true) { print”\n$a"; $a--; if($a==10)

25

Page 26: perl_5321

{ last; } }

Kết quả khi chạy chương trình là :

9.2 Toán tử next:

Toán tử next giống toán tử continue trong Pascal

Bỏ qua các lệnh còn lại trong thân vòng lặp để bắt đầu vòng lặp mới của lệnh lặp đó.

Ví dụ :

#!/usr/bin/perl

$a=20; $b=0; while($a>0) { print ”\n$b";

$a--; if($a>10) { next; } $b=$a; }

26

Page 27: perl_5321

Kết quả khi chạy chương trình :

9.3 Toán tử redo:

Lặp lại một lần vòng lặp.

While(dieu_kien) { #redo_se_nhay_toi_cho_nay phan_1; ... if(dieu_kien_nao_do){ phan_nao_do; ... redo; } phan_khac; ...}

9.4 Lệnh goto

Lệnh goto cho phép chương trình nhảy vô điều kiện tới một vị trí trong chương trình thông qua tên nhãn. Trong chương trình nhãn được đặt vào vị trí thích hợp theo sau là dấu hai chấm.

Dạng lệnh:

goto < nhãn >;

Ví dụ :

#!/usr/local/bin/perl

$a=1;

nhan: print “$a\n”;

27

Page 28: perl_5321

$a++;

if ( $a < 10 ) {

goto nhan;

}

Cũng như các ngôn ngữ bậc cao khác, tuy được trang bị lệnh nhảy goto song có thể nói ngôn ngữ lập trình Perl rất ít khi dùng lệnh goto vì lệnh goto làm mất tính cấu trúc của chương trình.

CHƯƠNG II: VÀO / RA DỮ LIỆU

1. Nhập dữ liệu vào:

1.1 Dùng toán tử STDIN:

- Trong Perl, cách phổ biến nhất để đọc dữ liệu vào từ bàn phím ta dùng toán tử STDIN (Standard Input):

Cú pháp: $x = <STDIN>;

- Toán tử <STDIN> sẽ báo cho trình biên dịch Perl biết để đọc một dòng từ thiết bị vào chuẩn, dòng này được xác định bởi kí tự kết thúc là ký tự chuyển sang dòng mới. Vì thế biến $x sẽ bao gồm cả kí tự chuyển sang dòng mới ( \n ). Để loại bỏ kí tự này đi Perl cung cấp cho ta một hàm chop loại bỏ kí tự cuối cùng của xâu.

chop($x);

- Tóm lại ta có quá trình nhậo dữ liệu vào từ bàn phím dùng toán tử <STDIN>như sau:

Thực chất toán tử <STDIN> ở đây là một file đại diện cho thiết bị vào chuẩn. Nhưng file này không cần mở bởi vì trình biên dịch Perl đã làm sẵn điều này cho ta.

- Đọc tất cả các dòng và xử lý trên mỗi dòng:

- Cứ mỗi khi một dòng được đọc vào, <STDIN> lại cho một giá trị đúng , cho nên chu trình tiếp tục thực hiện. Khi <STDIN> không còn dòng nào để đọc nữa thì nó cho lại undef , cho giá trị sai, kết thúc chu trình.

- Trong vòng lặp while, có thể viết gọn chop($_) thành chop; biến $_ là mặc định

28

Page 29: perl_5321

1.2 Vào dữ liệu bằng toán tử <>

- Cú pháp $x = <>;

- Toán tử này giống như <STDIN> ở chỗ nó trả về một dòng riêng trong ngữ cảnh vô hướng (undef nếu tất cả các dòng này đã được đọc), hay tất cả các dòng còn lại nếu được dùng trong ngữ cảnh riêng. Tuy nhiên, toán tử này sẽ lấy dữ liệu từ file hay các file được xác định trên dòng lệnh gọi chương trình. Chẳng hạn bạn có một chương trình với tên Myprog, khi bạn gọi chương trình với dòng lệnh sau:

Myprog file1 file2

Lúc này toán tử <> sẽ báo cho chương trình đọc từng dòng của file1, rồi từng dòng của file2. Kết quả cuối cùng trả về xâu rỗng báo hiệu kết thúc việc đọc.

- Nếu trong chương trình bạn có toán tử <> mà dòng lệnh không có các file thì toán tử <> sẽ đọc dữ liệu từ file vào chuẩn. Trong trường hợp này, toán tử <> tương đương với <STDIN>.

Trong trường hợp còn có một toán tử <> ở sau nữa thì thì lúc này toán tử <> cũng đọc từ file vào chuẩn.

1.3 Vào dữ liệu cho mảng:

@mg = <>;

@mg = <STDIN>;

Lúc này mỗi phần tử của mảng là một dòng dữ liệu từ thiết bị vào (là thiết bị vào chuẩn, hoặc là file).

1.4 Vào dữ liệu bằng dòng lệnh:

- Perl cho phép bạn lấy dữ liệu từ dòng lệnh bằng cách dùng một mảng đặc biệt là @ARGV. Khi chạy chương trình với một danh sách các biến, ví dụ:

Myprog file1 file2

Perl sẽ cho mảng @ARGV tương ứng với danh sách:

("file1", "file2")

Và giống như mọi mảng khác ta có thể truy nhập đến từng phần tử của mảng @ARGV.

Ví dụ sau sẽ minh hoạ cho rõ hơn về mảng @ARGV.

Cho chạy chương trình với dòng lệnh

hello Anh

29

Page 30: perl_5321

Kết quả sẽ in ra

Chao Anh

Perl làm việc với toán tở $ARGV như sau:

- Khi trình biên dịch Perl thấy <> lần đầu, nó sẽ mở file với tên được lưu trong $ARGV[0].

- Sau đó Perl sẽ thực hiện lệnh shift(@ARGV) , lệnh này sẽ bỏ đi phần tử đầu tiên của mảng @ARGV và dịch tất cả các phần tử của mảng lên một mức( phần tử i sẽ chuyển thành phần tử i-1).

- Tiếp theo toán tử <> đọc tất cả các dòng trong file được mở trong bước đầu.

- Khi đọc hết file, quay lại bước đầu và quá trình tiếp tục cho đến hết danh sách các file.

2. Xuất dữ liệu ra

- Có hai kiểu xuất dữ liệu ra là: + hiển thị trên màn hình

+ ghi lại ra file.

2.1. Dùng lệnh print:

- Cách đơn giản nhất để xuất dữ liệu ra là dùng lệnh print. Lệnh này nhận một danh sách các xâu rồi gửi lần lượt từng xâu ra thiết bị ra chuẩn (STDOUT) thường là màn hình.

print (“Xin chao”, “ban”);

Có thể bỏ dấu ( ) đi, tuy nhiên trong một số trường hợp ta cần phải có dấu ().

Ví dụ

Cũng như <STDIN>, thực chất toán tử <STDOUT> ở đây là một file đại diện cho thiết bị vào chuẩn.

2.2 Dùng printf:

- In dữ liệu định dạng dùng printf

- Lệnh printf trong Perl cũng tương tự như trong C với cú pháp như sau:

printf (<format>, [<argument>]);

<format> : hằng, xâu điều khiển việc đưa ra gồm các kí tự và quy cách ở dạng %.

[<argument>] : danh sách các đối số cần đưa ra, 1 đối số có thể là hằng, biểu thức, kí tự, xâu. Có bao nhiêu đối số đưa ra thì cần có bấy nhiêu quy cách tương ứng.

Bảng sau đây liệt kê mã định dạng cho các kiểu in khác nhau.

Quy cách Kiểu đối số

30

Page 31: perl_5321

%c Kí tự

%d Kiểu nguyên hệ 10

%e Kiểu thực dưới dạng số mũ

%f Kiểu thực dấu chấm tĩnh

%g In ra theo kiểu %e hoặc %f tuỳ theo cái nào ngắn hơn

%o Kiểu nguyên hệ 8

%s Kiểu xâu kí tự

%u Kiểu nguyên không dấu

%x Kiểu nguyên hệ 16

Ghi vị trí theo quy cách

- Đối với số nguyên hay xâu:

%md, %ms (mlà số nguyên) : cho biết số chỗ tối thiểu mà dữ liệu in ra sẽ chiếm. Nêu số in ra có số chữ số ít hơn m, máy sẽ in thêm các kí tự trống vào. Nếu số chỗ ta ghi mà không đủ thì máy sẽ tự động bổ sung cho đủ để in hết số.

- Đối với số thực :

%m.nf (m, n nguyên) : m là tổng số chữ số viết ra, n là số chữ số sau dấu phẩy.

- Đặc biệt nếu ta thêm dấu - vào trước m (%-md, %-ms, %-m.n ...), dữ liệu in ra sẽ được canh lề trái.

2.3. Định dạng dữ liệu ra

- Perl có một vài công cụ đặc biệt để bạn dễ dàng tạo ra những bản báo cáo đơn giản. Bản báo cáo gồm nhiều trang mà mỗi trang gồm có phần đầu đề, số trang và một vài thông tin khác sẽ giống nhau. Bạn có thể đặt số dòng cho mỗi trang, Perl sẽ tự động chuyển sang trang mới.

2.3.1. Định nghĩa một định dạng

Cú pháp

format <tên_định_dạng> =

<dòng_trường>

<dòng_giá_trị>

.

Dòng trường có thể chứa cả nơi giữ trường cho văn bản biến đổi. Nừu một dòng có chứa nơi giữ trường, thì dòng tiếp theo của tiêu bản (được gọi là dòng giá trị) sẽ mô tả cho một loạt các giá trị vô

31

Page 32: perl_5321

hướng – mỗi giá trị ứng với một nơi giữ trường – mà cung cấp ra giá trị sẽ được gắn vào trong trường. Sau đây là một ví dụ về dòng trường với một nơi giữ trường, và dòng giá trị đi theo:

format date =

===========================

|Ngay @<< thang @<< nam @<<<<|

$ngay, $thang, $nam

===========================

.

Kí hiệu @<< được gọi là nơi giữ trường, nó báo cho chương trình dịch Perl biết phải dành số chỗ là 2 cho giá trị của các biến được đưa ra và văn bản đưa ra được canh lề trái. Có bao nhiêu nơi giữ trường trong <dòng_trường> thì cần phải có bấy nhiêu biến được đưa ra trong <dòng_giá trị>.

Định nghĩa định dạng có thể được đặt ở bất kì đâu trong chương trình, tuy nhiên sẽ là tốt nhất nếu chúng ta đặt nó ở đầu hoặc cuối chương trình.

2.3.2. Hiển thị một định dạng

- Đặt biến hệ thống $~ bằng tên định dạng bạn cần gọi.

- Dùng hàm write để xuất dữ liệu.

Ví dụ

$~ = “date”;

write;

Lúc này nếu ta có $ngay = 20; #thang = 10; $nam = 2003, dữ liệu ra của bạn có dạng

===========================

|Ngay 20 thang 10 nam 2003 |

===========================

Chú ý : Nếu trong chương trình chính không có các biến được ghi trong <dong_gia_tri> ở định nghĩa định dạng thì dòng lệnh write; sẽ không được thực hiện.

Bảng định dạng trường dữ liệu

Trường Giá trị định dạng

@<<< Văn bản căn lề trái

@>>> Văn bản căn lề phải

@||| Văn bảncăn giữa

@##.## Định dạng số

32

Page 33: perl_5321

@* Văn bản nhiều dòng

Nếu một giá trị quá dài thì nó sẽ được chặt tự động.

Đối với dạng số @##.## Có nghĩa là dành 2 chỗ cho số đứng trước dấu . và hai số ở đằng sau. Giá trị của số sẽ tự đọng làm tròn.

Để in các kí tự đặc biệt @, <, > ta làm như sau:

format dacbiet =

Cac ki tu dac biet : @< @< @<

“@”, “<”, “>”

.

2.3.3. Ghi ra một file khác

Trong phần trước ta chỉ nói đến hàm write xuất dữ liệu ra thiết bị ra chuẩn <STDIN>, tuy nhiên bạn cũng có thể dùng hàm write để xuất dữ liệu ra một file bất kì

Cách đơn giản nhất là dùng lệnh

write (<tên_file>);

Tuy nhiên dữ liệu xuất ra file sẽ không được định dạng theo cách mà bạn đã định dạng trong chương trình, bởi vì biến $~ chỉ làm việc với một file ngầm định (file ra chuẩn <STDOUT> ). Để thay đổi file ngầm định này, làm cho biến $~ có hiệu lực, ta dùng hàm select :

select (<tên_file>);

Như vậy để xuất dữ liệu ra file theo định dạng mong muốn ta dùng đoạn lệnh sau

select (<tên_file>);

$~ = “<tên_định_dạng>”;

write;

Ví dụ:

Bởi vì hàm select đã thay đổi file để xuất dữ liệu ra, những lần gọi write và cả print về sau sẽ không cho ra thiết bị ra chuẩn, mà ghi vào file cho đến khi có dòng lệnh

select(STDOUT);

Tức là thay đổi file xuất dữ liệu ra là thiết bị ra chuẩn. Và bạn cũng thấy hàm print cũng ghi ra file đã chọn, cho nên trong lập trình cần phải chú ý tránh gây ra sự xáo trộn dữ liệu ra.

Để lưu lại file hiện thời đang xuất dữ liệu ra và chọn file mới ta dùng lệnh

$file_cu = select(<file_moi>);

Sau này muốn xuất dữ liệu ra file cũ, ta gọi lại

select($file_cu);

33

Page 34: perl_5321

2.4. Định dạng trang

2.4.1. Định dạng đầu trang

Định dạng đầu trang là một phần văn bản luôn xuất hiện ngay trên đầu của mỗi trang. Khi một định dạng đầu trang được định nghĩa, Perl sẽ tự động gọi định dạng đầu trang mỗi khi một trang mới được tạo ra. Để định nghĩa định dạng đầu trang ta định nghĩa một định dạng với tên như sau : <tên_file>_TOP (chữ TOP phải viết hoa)

Trong định dạng đầu trang có biến hệ thống thường hay được dùng là $%, biến này lưu số thứ tự của trang. Do đó ta có thể đánh số thứ tự cho từng trang.

Ví dụ

Lưu ý : mặc định $% = 0 và sẽ tự động tăng lên mỗi khi bắt đầu trang mới, do đó để thay đổi cách đánh số trang ta phải thay đổi giá trị của $% trước khi xuất dữ liệu.

Để thay đổi định dạng đầu trang ta thay đổi biến hệ thống $^

$^ = “dddtrang”;

2.4.2. Thay đổi số dòng của trang.

Mặc định số dòng của trang là 60. Muốn thay đổi số dòng, ta thay đổi giá trị của biến hệ thống $=

$= = 25; # Đặt số dòng cho trang là 25

Chú ý: Trình biên dịch Perl theo dõi số dòng trên trang bằng cách theo dõi lời gọi write. Vì thế nếu bạn sử dụng lệnh print sẽ gây xáo trộn. Nếu muốn đảm bảo sự đếm trang đồng bộ với sự đếm dòng thì ta cần phải thay đổi biến hệ thống $-. Biến này cho ta biết số dòng còn lại trên trang. Khi biến này nhận giá trị 0, định dạng đầu trang sẽ được tạo, một trang mới được tạo ra.

Ví dụ

2.4.3. Định dạng những xâu dữ liệu lớn

Trường giá trị @* sẽ in ra nhiều dòng văn bản. Tuy nhiên nó sẽ in ra chính xác những gì được lưu giữ trong xâu.

Ví dụ

34

Page 35: perl_5321

File VANBAN sẽ như sau :

Day la

vi

du

Để khắc phục nhược điểm này, Perl cho phép ta thay kí tự đầu @ bằng kí tự ^, trình biên dịch Perl sẽ xuất dữ liệu ra làm sao trên một dòng có nhiều kí tự nhất.

Ví dụ

Ta thay @* trong ví dụ trên bằng ^<<<<<<<<<<<<<<<<<

File VANBAN sẽ như sau :

Day la vi du

Nhiều khi ta không biết trước được dữ liệu ra dài từng nào cho nên ta định dạng nhiều dòng để tránh mất dữ liệu. Nhưng nếu dữ liệu ra ít thì ta sẽ nhận được những dòng trống. Muốn loại trừ những dòng trống này, hãy đặt kí tự ~ ở bất kì dòng dữ liệu ra nào, những dòng này sẽ được in ra nếu dữ liệu in ra không phải là xâu rỗng

format VANBAN =

~ ^<<<<<<<<<<<<<<<<<<<<<<

$xau

~ ^<<<<<<<<<<<<<<<<<<<<<<

$xau

~ ^<<<<<<<<<<<<<<<<<<<<<<

$xau

.

Ta có thể giảm bớt việc viết nhiều dòng giống nhau bằng cách đặt hai kí tự ~ ở đầu dòng định dạng dữ liệu ra :

format VANBAN =

~~ ^<<<<<<<<<<<<<<<<<<<<<<

.

35

Page 36: perl_5321

CHƯƠNG III: MẢNG, DANH SÁCH VÀ HASH

1. Danh sách (List):

1.1. Khái niệm danh sách:

- Một danh sách là một dãy các biến vô hướng sắp xếp theo thứ tự được đặt trong cặp ngoặc đơn ( ). Một danh sách có thể có bao nhiêu phần tử cũng được và chứa bất kì giá trị vô hướng nào.

Ví dụ:

(“Nguyen A”, 2, 4.5)

danh sách trên gồm có 3 phần tử : xâu Nguyen A và hai số 2, 4.5

(1, $a, $b + $c)

danh sách trên cũng có 3 phần tử : 1, giá trị của $a, giá trị của tổng $b + $c

- Các danh sách cũng có thể chứa các biểu thức dưới dạng một phần nội dung của chúng.

Ví dụ: (4+7, $a*$b, “Hello”, 10 )

Danh sách này chứa 4 giá trị vô hướng sau đây: 11, kết quả của biểu thức $a*$b, xâu hello và 10.

1.2. Khoảng danh sách

- Ta định nghĩa một danh sách bao gồm các số từ 0 đến 9 như sau:

36

Page 37: perl_5321

(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

Tuy nhiên có một cách đơn giản hơn là phải viết từng số ra. Perl cung cấp cho ta toán tử .. để định nghĩa danh sách có các phần tử nối tiếp nhau như sau

(1..10) danh sách gồm các số từ 1 đến 10

(“a”..”z”) danh sách gồm các chữ cái thường

($dau..$cuoi + 1) danh sách gồm các giá trị nằm trong khoảng từ giá trị của $dau đến giá trị của $cuoi+1

(1, 3..6, 8) danh sách gồm các phần tử 1, 3, 4, 5, 6, và 8

(1.5..4.1) danh sách gồm 1.5, 2.5, 3.5 (số 4.5 lớn hơn 4.1 nên không được đưa vào danh sách)

(3.4..1.2) danh sách này không có phần tử nào vì 3.4 > 1.2

- Ta cũng có thể dùng khoảng danh sách với xâu.

Ví dụ:

(“xxa”..”xxc”) tương đương với danh sách (“xxa”, ”xxb”, ”xxc”)

(“xxy”..”xxb”) tương đương với danh sách (“xxy”, ”xxz”, ”xxa”, “xxb”)

@ngay = (“01”..”31”);

tạo ra một mang @ngay chứa các phần tử là ngày trong tháng : 01, 02, ... 31

2. Mảng:

2.1. Khái niệm mảng:

- Mảng là một dãy dữ liệu cùng kiểu, được đặt dưới tên chung và lưu ở bộ nhớ trong, biến mảng được biểu thị bằng kí tự @ đầu tiên, tiếp theo sau là tên theo qui ước.

2.2. Khai báo:

@ <tên mảng> = (<các giá trị>);

Ví dụ:

@mang1 = (1, 2 , 3);

- Tên của mảng có thể trùng với tên của biến đã có

$mb = 7;

@mb = (4, 5, 6);

ở đây mb được sử dụng cho cả mảng @mb và biến $mb. Perl phân biệt được đâu là biến đâu là mảng nhờ vào kí tự đặc biệt @ và $. Tuy nhiên, không nên đặt tên theo kiểu này, dễ gây nhầm lẫn.

2.3. Truy nhập:

<tên_mảng> [<chỉ_số>]

37

Page 38: perl_5321

<tên_mảng> ở đây bắt đầu bằng kí tự $ chứ không phải là @ bởi vì ta truy nhập tới một phần tử riêng rẽ như là một biến vô hướng.

- Mảng trong Perl bắt đầu với chỉ số 0, do đó phần tử đầu tiên của mảng

@mang1 là $mang1[0], và nó có giá trị 1 như trên.

Chú ý:

Cần phân biệt giữa $mang1 và $mang1[0]

$mang1 : biến vô hướng

$mang1[0] : phần tử đầu tiên của mảng @mang1

Có thể gán một biến mảng cho một biến mảng khác.Ví dụ

@mang2 = @mang1;

Sau khi gán các phần tử của mảng @mang2 giống hệt các phần tử của mảng @mang1. Tức là $mang2[0] = $mang1[0], $mang2[1] = $mang1[1], ...

Có thể dùng mảng trong danh sách :

@mang2 = (“a”, @mang1, “c”);

Lệnh gán trên có nghĩa là gán danh sách (“a”, 1, 2, 3 , “c”) cho mảng @mang2( mảng @mang1 theo trên gồm có các phần tử 1, 2, 3)

Perl còn cho phép gán một mảng cho một danh sách các biến

($x, $y, $z) = @mang1;

tương đương với $x = $mang1[0]; $y = $mang1[1]; $z = $mang1[2];

Nếu số các biến nhiều hơn số các phần tử của mảng thì các biến cuối cùng được gán bằng xâu rỗng “”.

Ví dụ:

($x, $y, $z, $t) = @mang1;

$t sẽ dược gán bằng xâu rỗng.

Perl cho phép truy nhập tới nhiều phần tử của mảng cùng một lúc

<tên_mảng>[<chỉ_số_1>, <chỉ_số_2>, ... <chỉ_số_n>]

Ví dụ:

@mang_con1 = @mang1[0, 1];

@mang_con1 gồm hai phần tử đầu tiên của mảng @mang1.

@mang_con2 = @mang1[1, 2, 3];

@mang_con2 gồm ba phần tử 2, 3, 4 của mảng @mang1.

@mang_con3 = @mang1[0..9];

@mang_con3 gồm 10 phần tử đầu tiên của mảng @mang1.

@mang2[0, 1, 2] = (9, 8, 7);

ba phần tử đầu tiên của mảng @mang2 được gán bằng 9, 8, 7.

38

Page 39: perl_5321

@mang2[3..6] = (9, 8, 7);

tương đương với $mang2[3] = 9; $mang2[4] = 8; $mang2[5] = 7; $mang2[6] = “”;

Perl cung cấp một cách đơn giản để hoán đổi hai phần tử của mảng. Ví dụ muốn hoán đổi hai phần tử đầu tiên của mảng @mang1 chỉ cần dùng câu lệnh sau:

@mang1[0, 1] = @mang1[1, 0];

Sở dĩ làm được điều này vì Perl đã lưu @mang1[1, 0] vào một vị trí tạm thời trước khi gán, do đó sự hoán đổi diễn ra thành công.

2.4. Sắp xếp mảng

$n = @mang;for ($i=0; $i<$n-1; $i++)

for ($j=$i+1; $j<$n; $j++)if ($mang[$i] > $mang[j]) @mang[$i, $j] = @mang[$j, $i];

2.5. Số các phần tử của mảng

- Nếu một biến vô hướng được gán bằng tên của mảng thì biến đó chứa giá trị là số phần tử của mảng đó:

$sopt = @mang1; # $sopt nhận giá trị là 3 là số phần tử của mảng @mang1

Chú ý: Hai câu lệnh sau là không tương đương

$so = @mang1; # Số phần tử của mảng @mang1 gán cho $so.

($so) = @mang1; # Phần tử đầu tiên của mảng @mang1 gán cho $so.

Ở câu lệnh thứ hai ($so) được coi là một danh sách chỉ có duy nhất một phần tử $so.

2.6. In ra các phần tử của mảng

- Muốn in ra toàn bộ phần tử của mảng @mang1 ở trên ta dùng lệnh

print (@mang1);

Kết quả in ra sẽ là :

123

Để có khoảng trắng giữa các phần tử để dễ đọc hơn ta phải đưa biến mảng vào trong xâu “” :

print (“@mang1”);

Kết quả in ra

1 2 3

2.7. Một số hàm cho mảng

39

Page 40: perl_5321

2.7.1. Hàm sort

Hàm này sắp xếp các phần tử của mảng theo thứ tự alphabetical và trả lại giá trị là một danh sách được sắp xếp. Do đó ta có thể dùng phép gán :

@mang1 = (“de”, “bc”, “fg”, “a”);

@mang_sx = sort (@mang1);

Kết quả trả lại là @mang_sx gồm có các phần tử của mảng @mang1, nhưng được sắp xếp. Do đó @mang_sx là danh sách (“a”, “bc”, “de”, “fg”).

Muốn mảng @mang1 được sắp xếp, ta dùng lệnh

@mang1 = sort (@mang1);

Tức là giá trị trả lại sau khi sắp xếp @mang1 được gán chính vào @mang1

Chú ý : hàm sort chỉ sắp xếp được xâu, không sắp xếp được số theo thứ tự tăng dần. Do đó đoạn mã sau sẽ không thực hiện được điều ta mong muốn sắp xếp các số theo thứ tự :

@mang1 = (111, 33, 222);

@mang1 = sort (@mang1);

Bởi vì khi thực hiện hàm sort 111, 33, 222 được hiểu như là những xâu. Cho nên kết quả

@mang1 là danh sách (111, 222, 33)

2.7.2. Hàm reverse

Hàm này đảo ngược các phần tử của danh sách hay mảng, và giá trị trả lại là danh sách được đảo ngược.

@mang1 = (“de”, “bc”, “fg”, “a”);

@mang2 = reverse (@mang1);

Giá trị được gán cho mảng @mang2 là danh sách

(“a”, “fg”, “bc”, “de”)

Cũng như trên giá trị của mảng @mang1 không thay đổi, muốn có mảng @mang1 sắp xếp ta dùng:

@mang1 = reverse (@mang1);

2.7.3. Hàm chop

Hàm này cắt bỏ kí tự cuối cùng của mọi phần tử trong mảng :

@mang1 = (“abc”, “def”, “ghi”);

chop(@mang1);

Danh sách được lưu trữ trong mảng @mang1 sau khi thực hiện hàm chop là

(“ab”, “de”, “gh”);

2.7.4. Hàm join

40

Page 41: perl_5321

Hàm này ghép tất cả các xâu trong danh sách hay mảng trở thành một xâu:

$string = join(“ “, “Day”, “la”, “xau”);

phần tử đầu tiên của danh sách “ “ được coi là phần tử ngăn cách giữa các phần tử còn lại của danh sách trong xâu được ghép. Do vậy $string = “Day la xau”

2.7.5. Hàm split

Ngược với join hàm split tách một xâu ra thành những xâu con và giá trị trả lại là một danh sách. Các xâu con đượ tách nhờ vào dấu hiệu phân cách.

$string = “Day::la::xau”;

@mang1 = split(/::/, $string);

2.7.6. Hàm splice

Hàm splice cho phép bạn chỉnh sửa danh sách lưu trữ trong mảng như thêm phần tử vào giữa mảng, xoá phần tử hay thay thế một phần tử.

Thay đổi giá trị của phần tử

Thay đổi giá trị của phần tử thứ hai và ba của mảng @mang1 :

@mang1 = (“de”, “bc”, “fg”, “a”);

splice (@mang1, 1, 2, (“ij”, “kl”);

Nếu số phần tử thay thế nhiều hơn số phần tử chỉ định để thay thế, các phần tử còn lại được chèn vào danh sách

@mang1 = (“de”, “bc”, “fg”, “a”);

splice (@mang1, 1, (“ij”, “kl”); # Lại tạo ra mảng @mang1 giống như trên

Tương tự nếu số phần tử thay thế ít hơn thì các phần tử chỉ định thay thế còn lại trong danh sách sẽ bị loại bỏ

@mang1 = (“de”, “bc”, “fg”, “a”);

splice (@mang1, 1, 2, 3, (“ij”, “kl”);

@mang1 bây giờ chỉ còn 3 phần tử (“de”, “ij”, “kl”).

Thêm một phần tử vào mảng

splice (@mang1, 3, 0, "mn", "pq");

thêm hai phần tử “mn” và “pq” vào mảng @mang1, phần tử thứ 4 là “mn”, phần tử thứ 4 là “mn”, các phần tử thứ 4 và 5 của @mang1 sẽ được đẩy lên thành phần tử thứ 6 ,7 và tiếp tục.

Xoá phần tử khỏi mảng

splice(@mang1, m, n);

Xoá n phần tử của mảng n bắt dầu từ phần tử thứ m. Giá trị trả lại là một danh sách đã bị xoá các phần tử chỉ định.

41

Page 42: perl_5321

2.7.7. Hàm shift và unshift

- Hàm shift loại bỏ phần tử đầu tiên của mảng :

$ptdt = shift(@mang1);

Ngược lại hàm unshift chèn thêm vào đầu mảng một phần tử

unshift(@mang1, $ptdt);

2.7.8. Hàm push và pop

- Hàm push đẩy một phần tử vào cuối mảng

push(@mang1, $pt);

- Ngược lại hàm pop loại bỏ phần tử cuối cùng của mảng

pop(mang1);

hay $ptc = pop(mang1);

3. Mảng liên kết (Hash)

3.1. Khái niệm Hash

Với những mảng như trên, khi muốn truy cập tới một phần tử ta phải dùng chỉ số là số. Điều này sẽ gây khó khăn trong một số trường hợp, chẳng hạn ta muốn lưu trữ một danh sách các từ. Lúc đó phải xác định chỉ số nào tương ứng với từ nào, rất khó khăn.

Perl định nghĩa cho ta một kiểu mảng khác mà ta có thể truy cập tới từng phần tử của mảng nhờ vào chỉ số là giá trị vô hướng bất kì. Đó là mảng liên kết (associative arrays), đôi khi còn gọi là mảng băm (hash array).

- Tên của mảng liên kết được bắt đầu bằng kí tự %, phân biệt với mảng bình thường bắt đầu bằng @. Sau kí tự % là tên theo quy ước (phần tên này có thể trùng với tên của mảng thông thường đã có):

%manglk

3.2. Các thao tác trên mảng liên kết

- Tạo mảng liên kết

%<tên_mảng> = (<chỉ_số>, <giá_trị>, <chỉ_số>, <giá_trị>, ...);

hoặc dễ đọc hơn

%<tên_mảng> = (<chỉ_số>, => <giá_trị>, <chỉ_số>, =><giá_trị>, ...);

Ví dụ:

%mt = (“Pen4”, 3, “Pen3”, 2, “Celeron”, 5);

%ss = (“Tin4”, => 50, “Tin5”, => 48, “Tin6”, => 49);

42

Page 43: perl_5321

- Có thể tạo mảng liên kết từ mảng bình thường và ngược lại.

Ví dụ:

@mt = (“Pen4”, 3, “Pen3”, 2, “Celeron”, 5);

%mt = @mt; # Vẫn tạo ra mảng như trên.

@mt2 = %mt; # Tạo ra @mt2 giống @mt

Tạo mới mảng liên kết bằng cách truy cập tới mảng bằng chỉ số mới và gán cho nó giá trị :

$mt{“Pen2”} = 10;

- Xoá một phần tử của mảng dùng hàm delete:

delete($mt{“Celeron”});

- Việc truy nhập tới một phần tử của mảng liên kết có thể thông qua một chỉ số là một giá trị vô hướng bất kì

Cú pháp $<tên_mảng> {<chỉ_số>}

Ví dụ:

$manglk{“abc”} = 1;

$manglk{$cs} = “xyz”;

3.3 Một số hàm trên Hash:

3.3.1.Hàm key

key(%manglk) cho ta danh sách các chỉ số của mảng liên kết.

Ví dụ muốn in tất cả các phẩn tử của mảng liên kết %manglk :

foreach $ptu (keys(%manglk)) { print ("$ptu: $manglk{$ptu}\n");}vì hàm key trả lại danh sách, cho nên ta có thể dùng hàm sort để sắp xếp các chỉ số của mảng.

sort (keys(%manglk))

3.3.2.Hàm value

Hàm này trả lại giá trị là danh sách các giá trị của mảng liên kết

@giatri = value(%manglk)

3.3.3. Hàm each

each(%manglk) trả lại gía trị là một cặp giá trị vô hướng gồm chỉ số của một phần tử bất kì (Perl lưu giữ phần tử của mảng liên kết không theo thứ tự nào) và giá trị tương ứng của nó. Hàm này thường được dùng cho vòng lặp

43

Page 44: perl_5321

while (($cs, $gt) = each(%manglk)) {# Xử lí ở đây

}

3.3.4. Hàm exits

Kiểm tra xem có tồn tại phần tử trong danh sách liên kết

exits(@manglk{$key})

trả lại giá trị khác 0 nếu tìm thấy phần tử có khoá $key trong danh sách, bằng 0 nếu không tìm thấy.

3.4. Danh sách liên kết

3.4.1. Khái niệm:

Một danh sách liên kết là một cấu trúc dữ liệu đơn giản, trong đó các phần tử được nối với nhau bởi vùng kiên kết của chúng. Mỗi phần tử của danh sách liên kết gồm hai trường :

Giá trị của phần tử

Địa chỉ, hay con trỏ trỏ đến phần tử tiếp theo

Ngoài ra còn có biến địa chỉ đặc biệt để trỏ đến phần tử đầu tiên của danh sách

Trong Perl danh sách liên kết dễ dàng được tạo ra bằng cách sử dụng mảng liên kết, giá trị của phần tử này sẽ là chỉ số cho phần tử tiếp theo:

%tus = ("alpha", "beta",

"beta", "gamma",

"gamma", "delta",

"delta", "");

$header = "alpha";

3.4.2. Các thao tác đối với danh sách liên kết:

Giả sử cần tạo ra danh sách liên kết chứa các từ, ta thực hiện các bước như sau

a. Tạo danh sách rỗng

$header = “”;

b. Thêm một phần tử vào danh sách

- Nếu danh sách rỗng, thêm vào phần tử đầu tiên

if ($header eq "") { $header = $tu $dstu{$tu} = "";}

44

Page 45: perl_5321

- Nếu phải thêm vào đầu danh sách

$dstu{$tu} = $header;$header = $tu;- Các trường hợp còn lại thêm vào sau phần tử trỏ bởi chỉ số $pointer

$dstu{$tu} = $dstu{$pointer};$dstu{$pointer} = $tu;c. Xoá một phần tử khỏi danh sách

Giả sử cần xoá từ $tu trong danh sách

$pointer = $header;while ($dstu{$pointer} ne "" && $dstu{$pointer} ne $tu) { $pointer = $dstu{$pointer};}$dstu{pointer} = $dstu{$tu};

3.5. Kiểu dữ liệu có cấu trúc

3.5.1. Khái niệm

Kiểu dữ liệu có cấu trúc là một kiểu dữ liệu gồm tập hợp các phần tử dữ liệu có kiểu khác nhau nhưng có liên kết với nhau.

3.5.2. Dữ liệu có cấu trúc trong Perl

Trong Perl kiểu dữ liệu này không được định nghĩa một cách tường minh, mà ta phải dùng mảng liên kết để mô phỏng nó

Ví dụ:

C Perl

struct hocsinh { %hs = (“ten”,””.

char ten[20] “tuoi”,””);

int tuoi

} hs;

45

Page 46: perl_5321

CHƯƠNG IV: CHƯƠNG TRÌNH CON

1. Khái niệm:

- Trong Perl chương trình con là một đoạn chương trình nhằm thực hiện một công việc nào đó và được thực thi bằng cách gọi chương trình con đó ra.

- Mục đích sử dụng chương trình con:

+ Chia nhỏ chương trình thành những phần nhỏ hơn, làm cho nó dễ đọc và dễ hiểu hơn.

+ Giúp ta tránh phải viết lại nhiều lần những đoạn chương trình thực hiện một công việc giống nhau.

- Một chươngtrình con có thể gọi một chương trình con khác, và chương trình cobn khác này đến lượt nó lại có thể gọi chương trình con khác nữa, và cứ như thế, cho tới khi tất cả bộ nhớ có sẵn đã bị chất đầy bằng địa chỉ quay vể và các biểu thức được tính toán hết

- Định nghĩa chương trình con :

sub <tên> {

<các câu lệnh>

}

Khối các câu lệnh đi sau tên chương trình con trở thành định nghĩa CT con. Khi Ct con được gọi tới thì khối các câu lệnh tạo nên CT con này sẽ được thực hiện, và bất kỳ giá trị trả về nào (được mô tả sau đây) đều được trả về cho nơi gọi

Chẳng hạn sau đây là một Ct con:

<tên> : Được định nghĩa như phần tên giới thiệu trong chương 1, gồm các chữ cái, chữ số và dấu gạch dưới.

<các câu lệnh> : có thể có một hay nhiều câu lệnh.

- Chương trình con trong Perl có thể được đặt ở bất kì đâu trong chương trình chính. Tuy nhiên, sẽ là tốt nhất nếu đặt chương trình con ở đầu hoặc cuối chương trình chính. Điều này làm cho chương trình dễ đọc hơn.

- Trong Perl chỉ có một loại chương trình con duy nhất là hàm, song đoi khi tuỳ theo cách sử dụng mà ta được một CT con tương đương như là một thủ tục, tức là có thể gọi nó ra mà không cần gán.

Ví dụ: Theo trên ta có thể gọi: hello(); và chương trình sẽ in ra kết quả

Xin chao moi nguoi!

46

Page 47: perl_5321

2. Cách gọi hàm:

- Bạn gọi một CT con từ bên trong bất kỳ biểu thức nào bằng việc ghi ra tên của CT con và theo sau là danh sách các tham số được đặt trong hai dấu (), nếu không có tham số thì ta dùng ();

<tên> ( <danh sách các tham số> )

- Đôi khi gọi hàm bằng cách này gây ra lỗi, chương trình không hiểu , ta còn có cách gọi khác như sau luôn đúng :

&<tên> ( <danh sách các tham số> )

hay

do <tên> ( < danh sách các tham số> )

Ví dụ:

3. Trả lại giá trị cho hàm

- Là hàm thì phải có giá trị. Trong Perl giá trị của hàm được tình bằng giá trị của biểu thức cuối cùng trong hàm.

Hàm cho_gia_tri sẽ có giá trị bằng giá trị của $x là 123. Như vậy chỉ cần viết ra biến hay giá trị cuối cùng trong hàm ta nhận được giá trị trả lại cho hàm chính là biến hay giá trị đó. Tuy nhiên làm như vậy sẽ làm cho chương trình rất khó đọc.

Nên sử dụng biến mảng retval để gán giá trị trả lại cho hàm

$retval = $x;

@retval = @mang;

Tuy nhiên biểu thức cuối cùng ở đây là biểu thức được tính trong hàm chứ không phải là biểu thức cuối cùng xác đinh trong thân hàm.

Cũng có thể trả lại giá trị cho hàm bằng cách dùng câu lệnh

return <giá trị trả về>;

47

Page 48: perl_5321

Câu lệnh return này hành động giống hệt như trong C : trả lại giá trị cho hàm và kết thúc hàm chuyển về chỗ đã gọi nó.

4. Biến cục bộ trong hàm:

- Biến cục bộ là biến được khai báo trong hàm và chỉ tồn tại trong thời gian hàm đó hoạt động. Khi ra khỏi hàm biến đó mất đi, khi gọi hàm một lần nữa biến cục bộ lạ được định nghĩa lại.

- Biến cục bộ được khai báo như sau :

my <biến>;

local <biến> ;

Khai báo bằng từ khoá my làm cho biến đó chỉ tồn tại trong hàm đó. Ra khỏi ngoài hàm đó thì biến đó không còn tồn tại.

Khai báo bằng từ khoá local sẽ làm cho biến đó tồn tại trong hàm đó và cả trong những hàm được nó gọi. Nhưng sẽ không tồn tại trong chương trình chính.

Cũng như cách khai báo biến toàn cục, biến cục bộ có thể được gán giá trị trong khi khai báo

5. Truyền tham số cho hàm

- Trong Perl khi lời gọi hàm có một danh sách các tham số, các tham số đó sẽ tự động gán cho một danh sách với tên @_. Chương trình con xác định giá trị các tham số bằng cách truy cập vào danh sách các biến này.

Ví dụ:

Trong trường hợp này khi gọi hàm tổng biến $a được gán cho $_[0], biến $b được gán cho $_[1] và hàm tính tổng $a + $b.

Ta có thể dùng biến cục bộ chứa danh sách tham số để cho chương trình dễ đọc hơn :

48

Page 49: perl_5321

Truyền cả một danh sách cho hàm :

Xét ví dụ sau :

Với hàm này khi gọi, ta có thể truyền cho nó một mảng, một danh sách, hay một tập hợp danh sách hay tập hợp biến.

&addlist (@mang);

&addlist ("1", "2", "3");

&addlist ($a, @mb, $c);

Và khi khai báo biến cục bộ ta cũng có thể làm:

my (@list) = @_;

my (@list1, @list2) = @_;

my ($a, @mb, $c) = @)_;

Trong trường hợp thứ 3, $_[0] được gán cho biến $a, các phần tử tiếp theo của @_ là phần tử của mảng @mb, tiếp theo phần tử cuối được gán cho $c. Tuy nhiên trong một số trường hợp có thể $c = null, các phần tử còn lại của @_ được gán cho các phần tử của mảng @mb.

Truyền tham số bằng cách dùng bí danh(Passing Arrays by Name Using Aliases Không biêt dich có đúng không)

Như đã thấy, Perl cho phép truyền cả một mảng như là một tham số. Khi hàm được gọi, tất cả các giá trị của mảng tham số sẽ được truyền cho mảng @_ được định nghĩa trong hàm.

Nếu mảng được truyền quá lớn, sẽ mất nhiều thiều thời gian và bộ nhớ. Để làm cho chương trình có hiệu quả hơn, Perl cho phép truyền mảng tham số qua tên bằng cách thay @ bởi * trong lúc định nghĩa mảng trong hàm và trong lời gọi hàm.

49

Page 50: perl_5321

Khi hàm được thực hiện, nó sẽ dùng chính mảng thực truyền cho hàm để thao tác thay vì tạo ra một bản sao của nó. Lời gọi hàm với *mang thay vì @mang chỉ cho ta biết mảng thực @mang được sử dụng (và có thể được thay đổi nếu cần) trong hàm. Tức là khi hàm được thực hiện mảng @mang_con chính là mảng @mang, hay tên mảng @mang_con được đồng nhất với tên mảng @mang. Hay nói cách khác khi hàm được thực hiện @mang con có bí danh là @mang, và khi hàm kết thúc @mang_con không còn có bí danh @mang. Khi hàm được gọi lại với tham số khác, @mang_con lại có một bí danh mới.

Có thể nói đây là cách truyền tham bién trong Perl, bởi vì tất cả các sự thay đổi tham số trong hàm đều dẫn tới sự thay đổi trong chương trình chính.

Chú ý :

- Nếu có một biến và một mảng cùng tên thì cả biến và mảng đều có hiệu lực trong lời gọi hàm. Ví dụ:

- Ta cũng có thể truyền nhiều biến, mảng hay danh sách theo cách này

6. Hàm đệ qui

- Hàm đệ qui là hàm được định nghĩa qua chính nó và được xuất phát từ trường hợp cơ sở.

Ví dụ:

50

Page 51: perl_5321

7. Chỉ định thứ tự sắp xếp

- Ta có hàm sort trong Perl sẽ sắp xếp các phần tử theo thứ tự abc.

@list1 = ("Trang", "An", "Nam");

@list2 = sort (@list1);

cho ta @list2 = ("An", "Nam", "Trang")

- Để sắp xếp cần phải so sánh từng đôi cặp phần tử một. Perl làm điều này bằng cách gọi một hàm đăc biệt được xây dựng sẵn tương tự như hàm sau :

- Perl cũng cho phép bạn tự định nghĩa hàm sort_criteria (tiêu chuẩn sắp xếp) để sắp xếp một danh sách theo ý muốn của mình. Hàm này cần phải có câu trúc tương tự như trên, phải dùng hai biến toàn cục $a và $b và phải có một trong các giá trị trả về sau :

-1 Nếu biến $a được đứng trước biến $b trong danh sách sắp xếp

0 Nếu biến $a ngang hàng với biến $b trong danh sách sắp xếp

1 Nếu biến $a đứng sau biến $b trong danh sách sắp xếp

Lưu ý : Mặc dù các biến $a, $b là các biến toàn cục, nhưng nó không hề gây ảnh hưởng tới các biến toàn cục $a, $b (nếu có) ở trong chương trình chính. Các biến này trong chương trình chính sẽ được lưu giữ lại khi thực hiện sắp xếp và được trả lại khi sắp xếp xong.

Sau khi định nghĩa tiêu chuẩn sắp xếp ta gọi hàm sort để sắp xếp theo ý muốn.

sort <hàm tiêu chuẩn sắp xếp> (@list)

Ví dụ chương trình sau sẽ sắp xếp các số ra sau :

51

Page 52: perl_5321

Kết quả chương trình:

ba nam

bon nam

35

45

8. Một số hàm đặc biệt trong Perl

8.1. Hàm BEGIN

- Hàm này sẽ được gọi khi chương trình bắt đầu chạy.

BEGIN {

print “Chuong trinh ...\n”;

}

Tất nhiên cũng như mọi hàm khác, hàm này có thể có biến cục bộ hoặc có thể gọi hàm khác trong chương trình.

8.2. Hàm END

- Hàm này được gọi khi chương trình kết thúc.

END {

print “Ket thuc chuong trinh!”;

}

8.3. Hàm AUTOLOAD

- Hàm này sẽ được gọi khi có một lời gọi hàm, mà hàm này không được tìm thấy trong chương trình, tên của hàm được lưu trong biến AUTOLOAD, danh sách tham số được lưu trong @_:

52

Page 53: perl_5321

- Hàm AUTOLOAD rất có ích khi ta lập trình chia theo nhiều modul, nó sẽ kiểm tra sự tồn tại của một hàm nào đó được viết trong file khác khi hàm đó được gọi.

8.4. Các hàm toán học : sin, cos, atan2, sqrt, exp, log, abs

8.5. Hàm tạo số ngẫu nhiên : rand, srand

hex(hexnum) chuyển đổi số hexnum ở hệ 16 sang hệ 10.

$he10 = hex(ff); # $he10 nhận giá trị 255

oct(octnum) chuyển đổi số octnum ở hệ 8 sang hệ 10.

$he10 = oct(17); # $he10 nhận giá trị 15

int(floatnum) chuyển đổi số thực floatnum ra số nguyên.

$nguyen = int(37.6); # $nguyen nhận giá trị 37

$nguyen = int(37.6 + 0.5); # $nguyen nhận giá trị 38

ord (char) cho giá trị là số thứ tự của kí tự char trong bảng mã ASCII

char (num) cho giá trị là kí tự có số thứ tự là num trong bảng mã ASCII

53

Page 54: perl_5321

CHƯƠNG V: TỆP (FILE)

1. Khái niệm về tệp :

Tệp tin hay tệp dữ liệu là một tập hợp các dữ liệu có liên quan với nhau và có cùng một kiểu được nhóm lại với nhau thành một dãy. Chúng thường được chứa trong một thiết bị nhớ ngoài của máy tính (đĩa mềm, đĩa cứng...) dưới một cái tên nào đó. Do đó tệp tồn tại ngay cả khi chương trình kết thúc hay mất điện.

Sau đây chúng ta sẽ tìm hiểu các thao tác trên tệp trong Perl :

2. Các thao tác

2.1 Mở tệp

54

Page 55: perl_5321

Cú pháp open (filevar, filename);

filevar : là biến tệp dùng để thay thế cho tệp trong chương trình Perl.

filename : là tên có đường dẫn đầy đủ của tệp.

Biến filevar được đặt tên theo khái niệm về tên đã giới thiệu trong chương 1. Biến này không có kí tự đặc biệt ở đầu nên có thể lẫn lộn với tên biến hay một số từ dành riêng khác. Vì thế ta nên dùng chữ hoa để đặt tên biến tệp .

open (DULIEU, “c:\perl\eg\readme.txt”);

filename được Perl hiểu là một xâu nháy kép chỉ rõ vị trí của tệp. Vì thế ta có thể làm như sau :

$ten_tep = “c:\bootlog.txt”;

open (DULIEU, $ten_tep);

Chế độ mở tệp : có 3 chế độ mở

Mở đọc : đây là chế độ ngầm định của Perl.

Mở ghi : chế độ này sẽ mở tệp, xoá nội dung của tệp và bắt đầu ghi mới.

Cách mở : thêm kí tự > vào trước filename

open (DULIEU, “>c:\perl\eg\readme.txt”);

Mở ghi thêm vào : có thể thêm dữ liệu vào tệp mở mà không xoá nội dung của tệp.

Cách mở : thêm >> vào trước filename

open (DULIEU, “>>c:\perl\eg\readme.txt”);

Mở vừa đọc, vừa ghi : khác với chế độ ghi thêm vào, chế độ này cho phép ghi đè lên dữ liệu đã có, lại còn cho phép đọc tệp.

open (DULIEU, “+>c:\perl\eg\readme.txt”);

Cách mở : thêm +> vào trước filename

Kiểm tra quá trình mở : Hàm open sẽ trả lại giá trị 1/0 nếu quá trình mở tệp thành công hay không thành công. Vì thế ta có thể dùng lệnh if hay unless để thao tác :

if (open(MYFILE, "vanban.inp")) {

# xử lí tiếp nếu quá trình mở file thành công

}

Perl còn cung cấp cho ta hàm die để hiển thị thông báo lỗi trong quá trình mở tệp với cú pháp như sau :

die ( <thông báo> );

Ví dụ

unless (open(TEPVB, "dulieu.inp")) {

die (“khong mo duoc file ...\n”);

}

hoặc gọn hơn

open (TEPVB, "dulieu.inp") || die (“khong mo duoc file ...\n”);

55

Page 56: perl_5321

Nếu muốn có chính xác dòng gây ra lỗi ta bỏ kí tự \n trong dòng thông báo.

die (“Khong mo duoc file ... vi loi o dong”);

Mở tệp nhị phân : Phải khai báo sử dụng tệp ở chế độ nhị phân bằng cách dùng hàm binmode :

binmode (filevar)

hàm này phải được gọi sau khi mở tệp và trước khi đọc, ghi tệp.

2.2 Đọc tệp

Đọc một dòng

Để đọc một dòng từ tệp đã được mở ta dùng lệnh có cú pháp như sau :

$line = <filevar>;

Ví dụ : Chương trình in ra nội dung của tệp dulieu.inp

#!/usr/local/bin/perl

if (open(TEP, "dulieu.inp")) { $line = <TEP>; while ($line ne "") {

print ($line); $line = <TEP>;

}}

Perl còn cho phép đọc toàn bộ tệp vào một mảng, mỗi dòng của tệp là một phần tử của mảng :

@mang = <TEP>;

Đọc 1 kí tự

$char = getc(filename);

Đọc theo số byte

read (filevar, result, length, skipval);

sysread (filevar, result, length, skipval);

filevar : biến tệp.

result : biến vô hướng hay một phần tử của mảng để lưu kết quả.

lentght : độ dài byte cần đọc.

skipval : chỉ số byte cách quãng trước khi đọc(đối số này không cần thiết).

Hàm read và sysread cùng thực hiện việc đọc nhưng sysread thực hiện nhanh hơn.

Ví dụ đọc 4 byte từ tệp được lưu trong biến TEP và cho vào biến $x

read (TEP, $x, 4);

Cách đọc này thường được sử dụng cho tệp nhị phân, do đó phải khai báo cách đọc nhị phân.

Ví dụ : đọc tệp lưu trữ số nguyên 2 byte

56

Page 57: perl_5321

#!/usr/local/bin/perlopen (TEP, "songuyen.dat");binmode(TEP);while (read(TEP, $so, 2), !eof(TEP)) {

print ("$so\n");}

Hàm eof(TEP) ở trên dùng để kiểm tra xem đã đọc hết tệp chưa. Hàm này giống như trong C trả lại giá trị 0 nếu chưa đọc hết tệp, khác 0 nếu đọc hết tệp.

2.3 Ghi tệp

Cú pháp print filevar (<dữ liệu>);

printf filevar (<format>, <argument>);

Ví dụ

open(INFILE, "dulieu.inp")) || die ("Khong mo duoc file dulieu.inp\n");open(OUTFILE, ">dulieu.out")) || die ("Khong mo duoc file dulieu.out\n");}$line = <INFILE>;while ($line ne "") { print OUTFILE ($line);

$line = <INFILE>;}

Hoặc dùng hàm select để thay đổi tệp ra mặc định rồi dùng

print (<dữ liệu>);

hay dùng write cùng với định dạng dữ liệu ra để ghi như đã đề cập tới trong phần Vào/ra

Để ghi theo byte đối với tệp nhị phân phải dùng hàm syswrite

syswrite (filevar, data, length, skipval);

Các đối số như hàm read.

2.4 Truy cập trực tiếp tệp

Trong các thao tác đọc ở trước các tệp luôn được đọc theo kiểu tuần tự, từ đầu đến cuối tệp. Để có thể truy cập đến vị trí bất kì trong tệp, Perl cung cấp hàm seek

seek (filevar, distance, relative_to);

filevar : biến tệp

distance : số byte bỏ qua để nhảy tới vị trí mong muốn

relative_to : có ba giá trị 0 hoặc 1 hoặc 2

Nếu là 0 thì bước nhảy tính từ đầu tệp, 1 tính từ vị trí hiện tại và 2 thì tính từ toạ độ cuối tệp.

Ví dụ

Di chuyển đến đầu file :

57

Page 58: perl_5321

seek(TEP, 0, 0);

Di chuyển tiếp 10 vị trí từ vị trí hiện tại :

seek(TEP, 10, 1);

Di chuyển lùi lại 10 vị trí từ vị trí hiện tại :

seek(TEP, -10, 1);

Di chuyển đến cuối file :

seek(TEP, 0, 2);

Tuy nhiên, một vấn đề đặt ra là phải kiểm soát xem vị trí truy nhập vào có vượt ra ngoài kích thước tệp hay không. Để tránh gây lỗi, Perl cung cấp hàm tell xác định vị trí hiện tại của con trỏ tệp. Hàm này trả lại khoảng cách (bằng số byte) tính từ đầu tệp đến vị trí hiện tại.

Cú pháp tell(filevar)

Ví dụ : tính số byte của tệp

seek(TEP, 0, 2); # Di chuyển đến cuối tệp

$kichthuoc = tell (TEP);

2.5 Đóng tệp

Cú pháp close (filevar);

Tuy nhiên nếu quên không đóng tệp lại khi xử lý xong thì Perl sẽ làm giúp điều đó. Ví dụ

open (MYFILE, ">dulieu");print MYFILE ("Xin chao.\n");open (MYFILE, ">file2");print MYFILE ("Xin chaot.\n");

Khi file2 được mở ra Perl sẽ tự động đóng dulieu lại và biến MYFILE được thao tác với file2.

3. Kiểm tra tệp

Perl có rất nhiều toán tử cho ta sử dụng để kiểm tra các thuộc tính của tệp. Ví dụ như sử dụng toán tử -e để đảm bảo rằng tệp có tồn tại trước khi thao tác. Hay kiểm tra tệp xem có thể ghi được không trước khi viết thêm vào. Bằng việc kiểm tra tính khả thi của các thao tác đối với tệp, ta có thể giảm bớt số lỗi sẽ gặp.

Cú pháp -x $filevar

x : là kí tự chữ biểu thị toán tử kiểm tra tệp.

$filevar : là biến vô hướng chứa tên tệp.

Toán tử thường dùng nhất là toán tử kiểm tra tệp đó có tồn tại hay không -e

$var = "dulieu ";

if (-e $var) {

print STDERR ("File dulieu co ton tai.\n");

}

Bảng sau đây liệt kê các toán tử kiểm tra file :

58

Page 59: perl_5321

Toán tử Giải thích

-b $filevar có phải là file khối đặc biệt?

-c $filevar có phải là file kí tự đặc biệt?

-d $filevar có phải là thư mục?

-e $filevar có tồn tại?

-f $filevar có phải là một file?

-g $filevar được thiết lập thuộc tính setgid?

-k $filevar được thiết lập thuộc tính sticky?

-l $filevar có phải là symbolic link?

-o $filevar được sở hữu bởi người dùng?

-p $filevar có phải là pipe?

-r $filevar có phải là file đọc được?

-s $filevar có phải là file không rỗng?

-t $filevar là cuối cùng?

-u $filevar được thiết lập setuid?

-w $filevar có phải là file ghi được?

-x $filevar có phải là file thực thi?

-z $filevar có phải là file rỗng?

-A Cho số ngày kể từ khi $filevar được truy nhập lần cuối?

-B $filevar có phải là file nhị phân?

-C Cho số ngày kể từ khi inode của $filevar được truy nhập lần cuối?

-M Cho số ngày kể từ khi $filevar được thay đổi lần cuối?

-O $filevar có phải chỉ được sở hữu bởi người dùng thực?(đang login)

-R $filevar có phải chỉ được đọc bởi người dùng thực?

-S $filevar có phải là socket?

59

Page 60: perl_5321

-T $filevar có phải là file văn bản?

-W $filevar có phải chỉ được ghi bởi người dùng thực?

-X $filevar có phải chỉ được thực thi bởi người dùng thực?

Ví dụ

Kiểm tra tệp có đọc được không?

unless (open(TEP, "dulieu")) { if (!(-e "dulieu")) { die ("Tep dulieu khong ton tai.\n"); } elsif (!(-r "dulieu")) { die ("khong the doc duoc file dulieu.\n"); } else { die ("File dulieu khong the mo \n"); }

}

Kiểm tra tệp xem có rỗng không

if (-e "dulieu") { if (!(-w "dulieu")) { die ("Khong cho phep ghi tep dulieu.\n");

if (!(-z "dulieu")) { die ("Tep dulieu khong rong.\n");}

Tính kích thước của tệp dùng toán tử -s. Toán tử này trả lại số byte (kích thước) của tệp, tức là trả lại giá trị khác 0(được hiểu là đúng) nên có thể dùng trong biểu thức kiểm tra điều kiện.

$kt_file = -s “duulieu”;

hay

if (-s “duulieu”) { #nếu tệp du lieu khác rỗng

...

}

Các toán tử này cho ta rất nhiều thông tin về tệp, nhưng nhiều lúc ta cần một loạt các thông tin về tệp. Các toán tử không làm được điều này, mỗi toán tử chỉ cho được một thông tin. Do đó để nhận nhiều thông tin Perl cung cấp cho ta hàm stat() hoặc lstat()

Hàm stat() trả lại thông tin về tệp trong một mảng 13 phần tử. Tham số của hàm có thể là biến tệp hoặc tên tệp. Danh sách các thông tin được lưu trong mảng gồm có các biến vô hướng sau đây :

($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks)

Ví dụ

($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat("readme.txt");print("dev = $dev\n"); # ổ đĩa chứa tệp đóprint("ino = $ino\n"); # Con số bên trong tham khảo đến cho tệp

60

Page 61: perl_5321

print("mode = $mode\n"); # Sự chấp nhận cho tệpprint("nlink = $nlink\n"); # Số liên kết cứng tới tệpprint("uid = $uid\n"); # Số ID của người dùng tệpprint("gid = $gid\n"); # Nhóm ID của người dùng tệpprint("rdev = $rdev\n"); # Kiểu thiết bị lưu trữ tệpprint("size = $size\n"); # Kích thước tệpprint("atime = $atime\n"); # Lần cuối được truy nhậpprint("mtime = $mtime\n"); # Lần cuối được chỉnh sửaprint("ctime = $ctime\n"); # Lần cuối tình trạng tệp được thay đổiprint("blksize = $blksize\n"); # Kích thước khối tốt nhất cho các toán tử vào ra trên tệpprint("blocks = $blocks\n"); # Số khối được cấp cho tệp

Kết quả :

Hàm lstat() làm việc giống stat, nhưng đối số được truyền được cho rằng là liên kết kí hiệu.

4. Một số hàm xử lí tệp

rename(<tên_cũ>, <tên_mới>);

Hàm này dùng đổi tên tệp trên đĩa, và trả lại giá trị đúng nếu thành công, sai nếu có lỗi.

Để đảm bảo rằng không ghi đè lên file tệp đã có, ta nên dùng toán tử -e để kiẻm tra

-e "tep2" || rename (“tep1”, “tep2”);

unlink(filelist);

Hàm này trả về số tệp bị xoá trong danh sách.

@tepxoa = ("tep1", "tep2");

unlink (@tepxoa);

link (filename, linkname);

Hàm này tạo ra liên kết mới cho tệp linkname đến mục filename. Kết quả trả về là 1 hay 0 nếu thành công hay không thành công.

symlink (filename, linkname);

61

C:\Perl\bin\perl tttep.pl

dev = 2

ino = 0

mode = 33206

nlink = 1

uid = 0

gid = 0

rdev = 2

size = 1447

atime = 1004461200

Page 62: perl_5321

Hàm này cũng tạo liên kết cho tệp linkname, nhưng chỉ tạo liên kết về tên. Do đó nếu ta xoá mục filename thì linkname không tham chiếu đến đâu cả.

readlink (linkname);

Hàm này đọc tệp là biểu tượng liên kết đến một tệp khác (biểu tượng này được tạo ra từ hàm symlink).

Hàm sẽ trả lại giá trị là tên của tệp được liên kết. nếu linkname không phải là biểu tượng liên kết, readlink sẽ trả lại giá trị là xâu rỗng.

chmod (permissions, filelist);

Hàm chmod dùng để thay đổi quyền truy cập của tệp. permissions là thông số về quyền truy nhập mà ta muốn thiết lập cho tệp, thông số này phải nằm trong thông số chuẩn của tệp của UNIX. Ví dụ khi đặt permissions là 0777, có nghĩa cho tệp đó có thể đọc, ghi và thực thi bởi tất cả mọi người.

chown (userid, groupid, filelist);

userid : số ID của người chủ mới của tệp

groupid : nhóm ID mới được gán cho tệp

filelist : danh sách tệp được thay đổi

Để thay đổi chủ của tệp ta dùng hàm này. Giá trị trả về của hàm là số tệp được thay đổi.

truncate (filename, length);

Thay đổi dung lượng của tệp filename. length là số dung lượng mới mà ta muốn đặt cho tệp filename.

time( )

Hàm time trả về lượng thời gian bằng giây tính từ 1/1/1970 đến hiện tại.

gmtime( )

Hàm này chuyển đổi giá trị trả về của hàm time ra giờ GMT.

localtime( )

Hàm này chuyển đổi giá trị trả về của hàm time ra giờ tính trên máy tính đang sử dụng.

utime (acctime, modtime, filelist);

Hàm này thay đổi giờ truy cập và giờ chỉnh sửa mới cho tệp. acctime : giờ truy cập mới

modtime : giờ chỉnh sửa mới

filelist : danh sách các tệp được thay đổi

Ví dụ : thay đổi giờ truy cập và chỉnh sửa cho tep2 bằng giờ truy cập, chỉnh sửa của tep1

$acctime = -A "tep1";

$modtime = -M "tep1";

@filelist = ("file2");

utime ($acctime, $modtime, @filelist);

flock( )

Hàm này tương đương với lệnh flock trong UNIX, tham số là filevar.

62

Page 63: perl_5321

fcltn( )

Hàm này tương đương với lệnh fcltn trong UNIX, tham số là filevar.

5. Một số hàm cho thư mục(Directory)

mkdir( dirname, permissions);

Tạo ra thư mục mới với tên dirname, thư mục này có thông số permissions để xác định quyền truy nhập giống như trong hàm chmod.

Bảng sau đây liệt kê một số giá trị permissions cho thư mục

Giá trị Permission

0400 Cho phép đọc đối với người sở hữu tệp

0200 Cho phép ghi đối với người sở hữu tệp

0100 Cho phép thực thi đối với người sở hữu tệp

0040 Cho phép đọc đối với nhóm người sở hữu tệp

0020 Cho phép ghi đối với nhóm người sở hữu tệp

0010 Cho phép thực thi đối với nhóm người sở hữu tệp

0004 Cho phép đọc đối với tất cả mọi người

0002 Cho phép ghi đối với tất cả mọi người

0001 Cho phép thực thi đối với tất cả mọi người

chdir (dirname);

Đặt thư mục làm việc mặc định là dirname.

opendir (dirvar, dirname);

Mở thư mục dirname để có thể đọc các tệp hay thư mục con trong đó.

closedir (dirvar);

Đóng thư mục.

readdir (dirvar);

Trả lại giá trị là tên thư mục hay tệp trong thư mục có biến dirvar đã được mở. Tương tự như hàm read đối với tệp.

telldir (dirvar);

63

Page 64: perl_5321

Giống như hàm tell của tệp. Cho biết thư mục hiện tại.

seekdir(dirvar, location);

Giống như hàm seek của tệp. Di chuyển đến thư mục chỉ định.

rmdir (dirname);

Xoá thư mục.

CHƯƠNG VI: XÂU VÀ XỬ LÝ VĂN BẢN TRONG PERL

Mục đích ban đầu của Larry Wall là tạo ra Perl để hỗ trợ việc xử lý văn bản Vì thế Perl là một ngôn ngữ cực mạnh trong việc xử lý Text. Chương này sẽ tập trung minh hoạ rõ sức mạnh của Perl với các thao tác xử lý xâu và văn bản, điều mà ta phải khá vất vả khi thực hiện bằng ngôn ngữ C

Để thấy ngay lập tức đặc tính nổi bật này của Perl, ta hãy xét các thao tác sau:

Giả sử chúng ta có file ls.txt. File này là 1 file text chứa cơ sở dữ liệu từ bài báo cáo “British Educational”. Để in ra màn hình toàn bộ nội dung file trên, đơn giản chỉ cần gõ lệnh DOS sau: C:\>perl -ne "print" ls.txt | moreKết quả sẽ hiện ra như hình dưới và chờ người dùng ấn Enter để hiện trang tiếp theo

64

Page 65: perl_5321

Bây giờ ta lại muốn in ra tất cả các dòng có từ style, thì gõ lệnh sau:

C:\>perl -ne "print if /style/" ls.txt

Các phần cụ thể dưới đây sẽ giới thiệu chi tiết các hàm xử lý xâu và văn bản của Perl.

Trước tiên chúng ta làm quen với 1 thuật ngữ Pattern(dịch tiếng Việt là Khuôn mẫu). Đó là một dãy kí tự liên tiếp dùng để tìm kiếm trong xâu. Trong Perl một khuôn mẫu được bao quanh bởi hai kí tự vạch chéo :

/abc/

1. Toán tử đối sánh

Perl định nghĩa một toán tử đặc biệt để kiểm tra có hay không khuôn mẫu riêng biệt nằm trong xâu. Toán tử =~ kiểm tra có hay không khuôn mẫu phù hợp vả trả về một trong các giá trị sau :

65

Page 66: perl_5321

Khác 0, hay đúng nếu tìm thấy khuôn mẫu trong xâu.

0, hay sai nếu không tìm thấy khuôn mẫu.

Ví dụ

$kq = $xau =~ /abc/;

$kq sẽ nhận giá trị khác 0 nếu tìm thấy trong $xau có đoạn xâu abc, ngược lại nếu không tìm thấy $kq nhận giá trị 0.

Toán tử !~ ngược lại với toán tử =~, sẽ trả lại giá trị 0 nấu tìm thấy khuôn mẫu, khác 0 nếu không tìm thấy khuôn mẫu.

Nếu tìm thấy ta có hàm pos(st) chỉ ra vị trí của khuôn mẫu được đối sánh trong xâu.

while ($st =~ /i/g) { $vitri = pos($st); print("Tim thay o vi tri $vỉti\n");}

2. Các kí tự đặc biệt trong khuôn mẫu

2.1 Kí tự +

Với nghĩa “một hay nhiều kí tự trước đó”. Kiểu như khuôn mẫu /hi+!/ đối sánh với bất kì xâu nào dưới đây :

hi!

hii!

hiii!

...

Chú ý : Khuôn mẫu /an/ đối sánh với ann, annc, annn, ... (không đối sánh với an, vì đằng sau phải có thêm kí tự nữa).

Toán tử này đặc biệt hữu dụng khi ta muốn phân tách các từ của một xâu mà có nhiều khoảng trắng(dấu cách) (chỉ có dấu cách):

$wordcount = 0;$line = <STDIN>;while ($line ne "") { chop ($line); @words = split(/ +/, $line); $wordcount += @words; $line = <STDIN>;}print ("So tu duoc go la : $wordcount\n");

Lệnh @words = split(/ +/, $line) sẽ chia nhỏ xâu thành các xâu con được ngăn cách nhau bởi một hay nhiều dấu cách trong biến $line và gán vào mảng @word. Như vậy chương trình sẽ in ra số từ ta gõ vào.

2.2 Kí tự []

66

Page 67: perl_5321

Kí tự [] cho phép bạn định nghĩa khuôn mẫu mà đối sánh với một trong các kí tự trong danh sách

nằm giữa hai dấu ngoặc vuông.

Ví dụ

/[Bb]a/ đối sánh với khuôn mẫu Ba hoặc ba.

/[\t ]/ đối sánh với dấu tab hoặc dấu cách.

@words = split(/ [\t ]+/, $line);

phân chia $line thành các từ rồi gán vào trong mảng @word (các từ này được cách nhau bởi một hay nhiều khoảng trắng hay dấu cách).

Nếu có thêm kí tự ^ sau dấu [ thì có nghĩa là đối sánh với bất kì kí tự nào khác những kí tự nằm trong dấu ngoặc vuông.

Ví dụ

/12[^12]89/ đối sánh với mẫu như sau :

Bắt đầu bằng 12

Tiếp theo sau là kí tự không phải 1 hay 2

Cuối cùng là 89

2.3 Kí tự * và ?

Kí tự * đối sánh với 0 hoặc nhiều kí tự trước đó. Ví dụ /a*b/ đối sánh với ab, aab, aaab, ...

Kí tự ? đối sánh với 0 hoặc 1 kí tự trước đó.

2.4 Biểu diễn kí tự đặc biệt trong khuôn mẫu

Khi muốn trong khuôn mẫu có kí tự, bình thường là kí tự đặc biệt của khuôn mẫu, hãy thêm vào trước kí tự đó dấu sổ chéo \. Ví dụ muốn kiểm tra sự xuất hiện của một hay nhiều kí tự * trong xâu, dùng khuôn mẫu như sau :

/\*+/

tương tự với các kí tự +, /, (, ), [, ], ...

2.5 Đối sánh với bất kì kí tự hay chữ số

Muốn đối sánh một kí tự với một chữ số ta dùng khuôn mẫu

/[01223456789]/

Nhưng Perl cho phép bạn làm ngắn gọn hơn bằng cách chỉ ra điểm đầu và cuối của phạm vi đối sánh

/[0-9]/ đối sánh với chữ số

/[^0-9]/ đối sánh kí tự không phải chữ số

/[a-z]/ đối sánh với chữ thường

/[A-Z]/đối sánh với chữ hoa

67

Page 68: perl_5321

2.6 Khuôn mẫu mỏ neo

Perl cung cấp cho ta phương thức tìm kiếm mẫu trong xâu bằng cách dùng các khuôn mẫu được gọi là khuôn mẫu mỏ neo.

2.6.1 Khuôn mẫu ^ và $

Khuôn mẫu ^ và $ dùng để đối sánh với chỉ kí tự đầu hoặc cuối của xâu.

Ví dụ

/^hello/ đối sánh với các xâu có 5 kí tự hello ở đầu xâu.

/bye$/ đối sánh với các xâu có 3 kí tự bye ở cuối xâu.

Ta có thể dùng cả ^ và $ để đối sánh với một xâu

/^chao$/ đối sánh với xâu chao

2.6.2 Khuôn mẫu \b và \B

Khuôn mẫu \b dùng để đối sánh với mẫu được xuất hiện ở đầu từ hoặc cuối từ trong xâu :

/\babc/ đối sánh với những từ trong xâu được bắt đầu bằng abc

/abc\b/ đối sánh với những từ trong xâu được kết thúc bằng abc

/\babc\b/ đối sánh với từ abc trong xâu

Ví dụ

if ($line =~ /\bPerl\b/) { print “Co tu Perl trong xau”;

}

else print “Khong co tu Perl trong xau”;

Khuôn mẫu \B thì ngựơc lại với khuôn mẫu \b, nó đối sánh với khuôn mẫu được chứa trong từ.

/\Babc/ đối sánh với những từ trong xâu có abc như xyzabc, nhưng không đối sánh với abc

/\Babc\B/ đối sánh với xabcy, nhưng không đối sánh với abc, abcdef, xyzabc

2.7 Biến trong khuôn mẫu

Nếu muốn ta có thể sử dụng biến trong khuôn mẫu. Ví dụ

$mau = "[\\t ]+";

@words = split(/$mau/, $line);

2.8 Lớp kí tự được định nghĩa sẵn

Để tiện cho việc lập trình Perl định nghĩa sẵn một số lớp kí tự sau :

68

Page 69: perl_5321

Dãy mã Giải thích Khoảng

\d Bất kì chữ số nào [0-9]

\D Ngược với \d [^0-9]

\w Bất kì kí tự, chữ số , dấu _ [_0-9a-zA-Z]

\W Ngược với \w [^_0-9a-zA-Z]

\s Những khoảng trắng [ \r\t\n\f]

\S Không phải các khoảng trắng [^ \r\t\n\f]

2.9 Kí kự dấu chấm câu “.”

Kí tự này đối sánh với một kí tự bất kì ngoại trừ kí tự xuống dòng mới \n. Thường được sử dụng với kí tự *.

/1.*3/

khuôn mẫu này đối sánh với bất kì xâu nào có chứa kí tự 1 đứng trước kí tự 3.

Ví dụ nếu ta có xâu 123, 1023 thì xâu được đối sánh. Với xâu 123453 khuôn mẫu đối sánh là 123453 chứ không phải là 123 (vì tổ hợp kí tự *. sẽ cố tìm một khuôn mẫu đối sánh với nhiều kí tự nhất).

2.10 Xác định số lượng kí tự

Muốn xác định rõ số lượng kí tự trong khuôn mẫu, ta dùng khuôn mẫu

/ab{2}c/

khuôn mẫu này chỉ định số lượng kí tự b sau kí tự a là 2, có nghĩa là đối sánh với khuôn mẫu abbc

Ta có thể xác định khoảng số lượng kí tự dùng dấu “,” trong { và }

/ab{2,4}c/ số lượng kí tự b là từ 2 đến 4, tức là đối sánh với khuôn mẫu abbc, hay abbbc, hay abbbbc

/ab{2,}c/ số lượng kí tự b ít nhất là 2

/ab{0,2}c/ số lượng kí tự b nhiều nhất là 2, hay đối sánh với khuôn mẫu ac, hay abc hay abbc

/[0-9]{1,2}/ đối sánh với 1 hoặc 2 chữ số

2.11 Kí tự | (thay phiên)

Kí tự này chỉ định rõ hai hay nhiều hơn mẫu trong khuôn mẫu để mà lựa chọn

/abc|def/ khuôn mẫu này đối sánh với abc hoặ def

/[a-z]|[0-9]/ khuôn mẫu này đối sánh với hoặ là một chữ cái thường, hoặc là một chữ số

2.12 Cặp ( )

69

Page 70: perl_5321

Khi cho một khuôn mẫu nằm giữa hai dấu ngoặc (ab), Perl tự động ghi nhớ lại khuôn mẫu đó. Muốn lấy lại khuôn mẫu đó ta dùng kí tự \n (n ở đây là vị trí của kuôn mẫu được ghi nhớ).

Ví dụ

/(ab)c\1/ khuôn mẫu này tương đương với khuôn mẫu /abcab/

/(ab)c(9)\1ef\2\1/ khuôn mẫu này tương đương với khuôn mẫu /abc9abef9ab/

2.13 Biến chỉ đọc đặc biệt

Sau khi đối sánh khuôn mẫu thành công, các biến $1, $2, $3 vân vân sẽ được đặt cho cùng giá trị là \1, \2, \3 vân vân. Bạn có thể dùng điều này để nhìn vào một phần của việc đối sánh trong đoạn chương trình sau. Chẳng hạn:

$_ = “đây là phép kiểm tra”;

/(\W+)\W+(\W+)/; # đối sánh hai từ đầu

# $1 bây giờ là “đây” còn $2 bây giờ là “là”

Bạn cũng có thể thu được cùng các giá trị ($1, $2, $3 vân vân) bằng việc đặt đối sánh trong hoàn cảnh mảng. Kết quả là một danh sách các giá trị mà sẽ được đặt cho $1 cho tới số các vật được ghi nhớ, nhưng chỉ nếu biểu thức chính qui sánh đúng. Ta hãy lấy lại thí dụ trước theo cách khác

$_ = “đây là phép kiểm tra”;

($first, $second) = /(\W+)\W+(\W+)/; # đối sánh hai từ đầu

# $first bây giờ là “đây” còn $second bây giờ là “là”

Lưu ý rằng các biến $1 và $2 vẫn không bị thay đổi.

Các biến chỉ đọc được xác định trước còn bao gồm $&, mà là một phần của xâu sánh đúng với biểu thức chính qui; $`, là một phần của xâu trước phần sánh đúng; còn $’ là phần của xâu sau phần sánh đúng. Chẳng hạn:

$_ = “đây là xâu mẫu”;

/xâ.*u/; # sánh “xâu” bên trong xâu

# $` bây giờ là “đây là”

# $& bây giờ là “xâu”

# $’ bây giờ là “mẫu”

Vì tất cả những biến này đều được đặt lại cho từng lần sánh thành công cho nên bạn nên cất giữ các giá trị trong các biến vô hướng khác nếu bạn cần các giá trị đó về sau trong chương trình.

2.14 Thứ tự ưu tiên của các kí tự đặc biệt

Cũng giống như phép toán, các kí tự đặc biệt trong khuôn mẫu cũng có thứ tự ưu tiên, kí tự nào có thứ tự ưu tiên cao hơn thì được thực hiện trước. Bảng sau đây liệt kê thứ tự ưu tiên của các kí tự đặc biệt trong khuôn mẫu:

Kí tự Giải thích

() Khuôn mẫu ghi nhớ

70

Page 71: perl_5321

+ * ? {} Số kí tự bội

^ $ \b \B Khuôn mẫu mỏ neo

| Thay phiên

2.15 Kí tự đặc biệt chỉ định danh giới khuôn mẫu

Bình thường tất cả các khuôn mẫu được định nghĩa giữa hai dấu / . Vì thế muốn có kí tự / trong khuôn mẫu ta phải dùng \/. Nhưng như thế tật là bất tiện nếu ta muốn tìm thư mục như /user/perl/bin

/\/user\/perl\/bin/

Để làm đơn giản hơn Perl cho phép ta làm như sau

m!/user/perl/bin!

Lúc này m được hiểu như là toán tử chỉ định danh giới khuôn mẫu thay cho hai dấu /

Khuôn mẫu lúc này được bao quanh bởi hai dấu !. Tương tự ta có thể chỉ định kí tự khác làm danh giới khuôn mẫu nhưng nhất thiết phải có kí tự m đứng trước.

3. Tuỳ chọn khuôn mẫu đối sánh

Khi chỉ định khuôn mẫu, ta có thể sử dụng thêm một vài tuỳ chọn để điều khiển khuôn mẫu được đối sánh như thế nào.

Bảng sau đây liệt kê những tuỳ chọn đó

Tuỳ chọn GIẢI THÍCH

g Lấy tất cả các khuôn mẫu có thể

i Bỏ qua chữ hoa, thường

m Coi xâu như nhiều hàng

o Chỉ ước lượng một lần

s Coi xâu là một hàng

x Bỏ qua khoảng trắng trong khuôn mẫu

Tất cả các tuỳ chọn này đều được đặt ngay sau khuôn mẫu. Ví dụ

/abc/i

Một khuôn mẫu có thể có nhiều tuỳ chọn và không cần phân biệt thứ tự tuỳ chọn:

/abc /isx

71

Page 72: perl_5321

3.1 Tuỳ chọn g

Tuỳ chọn này báo cho Perl biết phải lấy tất cả các khuôn mẫu phù hợp trong xâu. Ví dụ đối với xâu banana ta sử dụng khuôn mẫu

/.a/g

thì các khuôn mẫu được lấy ra trong xâu là ba, na. Do đó có thể dùng một mảng để lấy ra tất cả các khuôn mẫu trong xâu

@mau = “banana” =~ /.a/g;

Mảng @mau bấy giờ gồm

(“ba”, “na”)

3.2 Tuỳ chọn i

Tuỳ chọn này cho phép bỏ qua sự phân biệt chữ hoa và chữ thường.

Ví dụ khuôn mẫu sau đối sánh với ab, Ab, aB, hay AB

/ab/i

3.3 Tuỳ chọn m

Tuỳ chọn này báo cho Perl biết xâu được đối sánh có chứa nhiều dòng văn bản. Khi có Tuỳ chọn m, kí tự đặc biệt ^ đối sánh với cả bắt đầu chuỗi hay bắt đầu dòng mới:

3.4 Tuỳ chọn s

Tuỳ chọn này cho biết xâu được đối sánh xem như là một dòng văn bản. Trong trường hợp này kí tự đặc biệt . được đối sánh với mọi kí tự trong xâu kể cả kí tự chuyển sang dòng mới \n. Do đó khuôn mẫu /a.b/s được đối sánh thành công đối với xâu

axxxxxxxxxx \ nxxxxb

3.5 Tuỳ chọn x

Tuỳ chọn này cho phép ta sử dụng các khoảng trắng trong khuôn mẫu mà không làm ảnh hưởng đến khuôn mẫu. Điều này làm cho khuôn mẫu dễ đọc, dễ hiểu hơn

/\d{2} ([\W]) \d{2} \1 \d{2}/x

Đến đây, khuôn mẫu có chứa khoảng trắng ta thêm \ vào trước khoảng trắng cần chỉ định

/[A-Z] [a-z]+ \ [A-Z] [a-z]+ /x

Tuy nhiên nếu có khoảng trắng trong khuôn mẫu thì không nên sử dụng tùy chọn x để tạo ra các khoảng trắng.

72

Page 73: perl_5321

4. Toán tử thay thế

Perl cho phép thay thế phần của xâu sử dụng toán tử thay thế với cú pháp như sau

s/pattern/replacement/

pattern Khuôn mẫu được tìm

replacement Xâu thay thế

Ví dụ thay từ name bằng từ ten trong xâu $xau

$xau =~ s/name/ten/;

Kết quả :

Trước khi gán $xau = “name : Van”

Sau khi gán $xau = “ten : Van”

Hay xoá tất cả các chữ số trong xâu

s/[0-9]//

Ta không thể dùng các kí tự đặc biệt ở phần replacement giống như trong khuôn mẫu bởi vì phần này thực sự là một xâu. Do đó khuôn mẫu sau

s/[a-z]/[0-9]/

không phải thay thế một chữ cái bằng một chữ số, mà là thay thế một chữ cái bằng [0-9]

Chú ý : Toán tử thay thế cũng có một vài giống như những tuỳ chọn trong khuôn mẫu đối sánh.

5. Toán tử truyền đạt

Có một cách khác để thay thế một nhóm kí tự bằng nhóm khác : toán tử tr sẽ làm điều đó :

Cú pháp tr/string1/string2/

string1 là xâu chứa danh sách các kí tự sẽ được thay thế

string2 là xâu chứa danh sách các kí tự thay thế

kí tự đầu tiên trong string1 dược thay thế bởi kí tự đầu tiên trong string2 và tiếp tục.

Ví dụ $string =~ tr/abc/def/;

Các kí tự được thay thế như sau

Tất cả các kí tự a được thay thế bởi kí tự d

Tất cả các kí tự b được thay thế bởi kí tự e

Tất cả các kí tự c được thay thế bởi kí tự f

$xau =~ tr/A-Z/a-z/; Chuyển đổi tất cả các chữ hoa trong xâu thành chữ thường.

Nếu xâu chứa kí tự được thay thế chứa nhiều kí tự hơn xâu thay thế, kí tự cuối cùng trong xâu thay thế được lặp lại

Ví dụ $string =~ tr/abcd/efg/;

73

Page 74: perl_5321

Kí tự d chưa có kí tự thay thế, do đó nó sẽ lấy kí tự cuối cùng trong xâu thay thế là g để thay thế nó. Có nghĩa là mọi kí tự d trong $string được thay thế bằng g

Nếu xâu chứa kí tự được thay thế có chứa nhiều kí tự giống nhau, kí tự thay thế đầu tiên được sử dụng

$xau =~ tr/aba/def/; thay thế a bởi d

Với toán tử truyền đạt có 3 tuỳ chọn

Tuỳ chọn c thay thế tất cả các kí tự mà không được chỉ định

$xau =~ tr/\d/ /c;

thay thế tất cả các kí tự không phải chữ cái bằng dấu cách

Tuỳ chọn d xoá bỏ mọi kí tự được chỉ định

$string =~ tr/\t //d;

Xoá mọi khoảng trắng trong xâu

Tuỳ chọn s kiểm tra dữ liệu ra từ truyền đạt.

6. Khuôn mẫu đối sánh mở rộng

Cú pháp (?<c>pattern)

<c> là một kí tự đại diện cho khuôn mẫu đối sánh mở rộng được sử dụng và pattern là khuôn mẫu hay khuôn mẫu con được sử dụng.

6.1 Khuôn mẫu con được đặt trong hai dấu ngoặc đơn không được lưu vào bộ nhớ

(?:a|b|c)(d|e)f\1/

Đối sánh với

Một kí tự a, b, hay c

Một kí tự d hay e

f

Tiếp theo là d hoặc e

ở đây \1 được tham chiếu tới (d|e) chứ không phải (?:a|b|c) vì (?:a|b|c) không được lưu vào bộ nhớ.

6.2 Cho tuỳ chọn vào trong khuôn mẫu

Ta có thể cho tuỳ chọn vào trong khuôn mẫu với cú pháp như sau

(?option)

Ví dụ

/(?i)[a-z]+/

khuôn mẫu trên tương đương với

/[a-z]+/i

74

Page 75: perl_5321

Với cách này ta có thể tạo ra được khuôn mẫu có tuỳ chọn được cho vào trong biến

$mau = “(?i)[a-z]+”;

$kq = $xau =~ /$mau/;

6.3 Đối sánh có điều kiện

/abc(?=def)/

Khuôn mẫu mày chỉ đối sánh với abc nếu đằng trước nó là def.

/abc(?!def)/

Khuôn mẫu mày chỉ đối sánh với abc nếu đằng trước nó không là def.

6.4. Chú thích cho khuôn mẫu

Cú pháp (?# Chu thich)

/[a-z]+(?# Doi sanh voi mot hoac nhieu chu cai)/i

7. Các Hàm split() và join()

Biểu thức chính qui(mẫu đối sánh) có thể được dùng để chặt một xâu thành các trường. Toán tử split() thực hiện điều này còn toán tử join() lại có thể dính các mẩu lại với nhau.

7.1 Hàm split()

Hàm split() nhận một biểu thức chính qui và một xâu rồi tìm tất cả mọi sự xuất hiện của biểu thứcchính qui bên trong xâu này (dường như bạn đã thực hiện toán tử s///g). Các bộ phận của xâu không sánh với biểu thức chính qui sẽ được cho lại lần lượt như một danh sách các giá trị. Chẳng hạn, sau đây là một cách phân tích các thành tố /etc/passwd:

$line = “merlyn::118:10:Randal:/home/merlyn:/usr/bin/perl”;

@fields = split(/:/,$line); # chặt $line ra, dùng : làm dấu định biên

# bây giờ @field là (“merlyn”, “”, “118”, “10”, “Randal”,

# “/home/merlyn”,”/usr/bin/perl”)

Lưu ý rằng trường thứ hai rỗng trở thành một xâu rỗng. Nếu bạn không muốn điều này, hãy đối sánh tất cả các hai chấm trong một lần phân tách:

@fields = split(/:+/, $line);

Điều này sẽ sánh cả hai dấu hai chấm đi kèm, cho nên sẽ không có trường thứ hai rỗng nữa.

Một xâu thông dụng để chặt biến $_, và biến thành mặc định là:

$_ = “xâu nào đó”;

@words = split(/ /); # hệt như @words = split(/ /, $_);

Lưu ý rằng đối với việc chặt này, các khoảng cách liên tiếp trong xâu cần chặt sẽ gây ra các trường không (xâu rỗng) trong kết quả. Một khuôn mẫu tốt hơn sẽ là / +/, hay một cách lí tưởng /\s+/, mà sẽ đối sánh một hay nhiều kí tự khoảng trắng. Trong thực tế, khuôn mẫu này là khuôn mẫu mặc định, cho nên nếu bạn định chặt biến $_ theo các khoảng trắng, thì bạn có thể dùng tất cả các mặc định

75

Page 76: perl_5321

và đơn thuần nói:

@words = split; # hệt như @words = split(/\s+/, $_);

Các trường theo sau rỗng không trở thành một phần của danh sách. Điều này nói chung không cần quan tâm - một giải pháp giống thế này:

$line = “merlyn::118:10:Randal:/home/merlyn:/usr/bin/perl”;

($name, $password, $uid,$gid,$gcos,$home,$shell) =

split(/:/, $line); # chặt $line ra bằng cách dùng : làm dấu định biên

sẽ đơn thuần cho $shell một giá trị không (undef) nếu dòng này không đủ dài, hay nếu nó chứa các giá trị rỗng trong trường cuối. (Các trường phụ thì im lặng bị bỏ qua, vì việc gán danh sách làm việc theo cách đó.)

7.2 Hàm join()

Hàm join() nhận một danh sách các giá trị và gắn chúng lại với nhau dùng xâu gắn giữa từng phần tử danh sách. Nó trông tựa như thế này:

$bigstring = join($glue, @list);

Chẳng hạn, để xây dựng lại dòng mật hiệu, bạn hãy thử một cách kiểu như:

$outline = join(“:”, @fields);

Lưu ý rằng xâu gắn không phải là biểu thức chính qui - chỉ là một xâu bình thường gồm không hay nhiều kí tự.

INDEX A – LIST MÃ NGUỒN BÀI TẬP TẦN SUẤT TỪ

Yêu cầu: Tại giao diện của chương trình, người sử dụng nhập tên một file văn bản(nội dung file đó bằng tiếng Anh). Chương trình sẽ in ra một file khác(và có in ra màn hình) tất cả các từ xuất hiện

76

Page 77: perl_5321

trong văn bản đó và tần suất tương ứng của mỗi từ.1.List mã nguồn bằng ngôn ngữ Perl1.1 Chương trình sử dụng List

################################################ #

# ## Chuong trinh : Doc vao tep van ban, ## dau ra danh sach tat ca ## cac tu cung tan suat. ## Ten file : LKTU.PL # # Dich (UNIX) : chmod +x lktu.pl ## (WIN) : perl lktu.pl ## Chay : LKTU <TEN_TEP_VAN_BAN> ## Han che : Khong coi tat ca cac ## ki tu dac biet co trong tu. ## ################################################

#!/usr/local/bin/perlif ($ARGV[0] eq "") { print " Ban nen dung lenh : lktu <ten_tep_van_ban>\n"; print (" Bay gio hay cho ten tep : "); $tentep = <STDIN>; chop($tentep);} else {

$tentep = $ARGV[0];}unless (open(TEP, $tentep)) {

if (!(-e $tentep)) { die (" Tep $tentep khong ton tai.\n"); } elsif (!(-r $tentep)) { die (" Khong the doc duoc file $tentep.\n"); } else { die (" Tep $tentep khong the mo duoc. \n"); }

}

# Tao danh sach lien ket rong, su dung danh sach lien ket de chua tu$header = "";

while ($line = <TEP>) { # Thay tat ca cac ki tu dac biet bang dau cach

$line =~ s/[\W]/ /g; # Thay tat ca cac chu so bang dau cach $line =~ s/[\d]/ /g; # Xoa bo tat ca cac khoang trang o dau va cuoi xau

$line =~ s/^\s+|\s+$//g; @words = split(/\s+/, $line); foreach $tu (@words) {

# Bo cac dau cham cau $tu =~ s/[\.,;:?-]$//g; # Chuyen tat ca cac chu trong tu thanh chu cai thuong $tu =~ tr/A-Z/a-z/;

# Cho chu cai dau thanh chu hoa$tu = ucfirst($tu);# Chuyen vao trong danh sach

&them_tu($tu); }}

77

Page 78: perl_5321

close (TEP);&in_kq;

$tentepkq = $tentep;$tentepkq =~ s/\..*//g;$tentepkq .= ".kqu";print " Ket qua nay duoc luu tru trong tep $tentepkq\n";&ghi_ra_tep;

sub them_tu { local($tu) = @_; local($pointer); # Neu danh sach rong thi them vao phan tu dau tien if ($header eq "") { $header = $tu;

$mang_tu{$tu} = ""; $dem{$tu} +=1;

return; } # Neu tu trung voi tu cua phan tu dau tien trong danh sach if ($header eq $tu){

$dem{$tu} +=1; return;}

# Neu tu them vao se la phan tu dau tien trong danh sach if ($header gt $tu) { $mang_tu{$tu} = $header; $header = $tu;

$dem{$tu} +=1; return; } # Tim cho thich hop de them tu vao danh sach $pointer = $header; while ($mang_tu{$pointer} ne "" && $mang_tu{$pointer} lt $tu) { $pointer = $mang_tu{$pointer}; } # Neu tu them vao da co if ($tu eq $mang_tu{$pointer}){

$dem{$tu} +=1; return;}

$mang_tu{$tu} = $mang_tu{$pointer}; $mang_tu{$pointer} = $tu;

$dem{$tu} +=1;}

sub in_kq { local ($pointer); print ("\nDanh sach cac tu trong tep $tentep :\n\n");

print ("-" x80);print ("| Tu TS " x 4);print ("-" x80);

$pointer = $header; while ($pointer ne "") {

printf ("| %-14s",$pointer); printf ("%3d ",$dem{$pointer}); $pointer = $mang_tu{$pointer};

}

78

Page 79: perl_5321

print ("\n","-" x 80,"\n");

sub ghi_ra_tep {local ($st, $st1, $pointer);open(TEPKQ, ">$tentepkq") || die "Nhung khong mo duoc de ghi";print TEPKQ ("\n Danh sach cac tu trong tep $tentep :\n\n");print TEPKQ ("-" x 93 ,"\n");print TEPKQ ("| Tu TS " x 4, "|\n");print TEPKQ ("-" x 93,"\n");

$pointer = $header;$st = 0;

while ($pointer ne "") { $st++;

printf TEPKQ ("| %-17s",$pointer); printf TEPKQ ("%3d ",$dem{$pointer}); if ($st % 4 == 0) { print TEPKQ ("|\n"); } $pointer = $mang_tu{$pointer};

}# Ve not cac duong ke con thieu$st1 = $st % 4;if ($st1 != 0) { while ($st1 != 4) {

printf TEPKQ ("%-23s","|"); $st1++;

} print TEPKQ ("|\n"); }

print TEPKQ ("-" x 93,"\n");print TEPKQ (" Tong so co : $st tu.");

}

1.2 Kết quả:

79

Page 80: perl_5321

Phần cuối:

2. Tham khảo chương trình C

Yêu cầu: giả thiết người dùng đã có hai file dạng text:

- TAILIEU.TXT: file chứa nội dung văn bản, được cấu trúc theo trang

- TUKHOA.TXT: file chứa các chuỗi từ khoá cần tìm kiếm, mỗi chuỗi từ khoá được đặt trên một dòng.

Người sử dụng muốn tạo ra một tệp có tên là CHISO.TXT chứa kết quả tìm kiếm. Các dòng của tệp được cấu trúc như sau:

80

Page 81: perl_5321

<Chuỗi từ khoá>: <Danh sách các trang xuất hiện chuỗi từ khoá phân cách nhau bằng dấu phảy>

VD: ĐHBK: 2,19,32

Trường hợp chuỗi từ khoá không xuất hiện trong bất cứ trang nào thì không ghi số hiệu trang. Đồng thời không phân biệt chữ hoa chữ thường, không phân biệt số dấu cách giữa các từ, VD: ta có chuỗi từ khoá cần tìm sau:

“Trường Đại học Bách Khoa Hà Nội”

thì chuỗi trong tệp văn bản:

“ TRường Đại Học BáCH KHOA Hà Nội “

vẫn được coi là tương đương với chuỗi từ khoá trên. Và cả trường hợp khi chuỗi từ khoá nằm trên 2 dòng khác nhau thì vẫn được coi là tìm thấy.

Với yêu cầu như trên nếu thực hiện bằng C sẽ có mã nguồn như sau:

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <alloc.h>

#define DEFAULT

#define MAX_LINE_LEN 256

#define MAX_KW_LEN 50

#define LINES_PER_PAGE 25

#define MALLOC(x) ((x *)malloc(sizeof(x)))

typedef char Keyword[MAX_KW_LEN];

typedef struct ResultNode{

int pageNum; // Page Number

struct ResultNode *next;

};

typedef struct KeywordNode{

char keyword[MAX_KW_LEN];

struct ResultNode *firstRN; // First Result Node

struct ResultNode *lastRN; // Last Result Node

struct KeywordNode *next;

};

81

Page 82: perl_5321

FILE *sf,*kf,*df; // Source/Keyword/Destination File

char scfile[80],kwfile[80],idfile[80];

struct KeywordNode *head; // Point to keyword list

void Init(void);

int GetPageNum(int lineNum);

void Standardlize(char *st);

void MakeKeywordList(struct KeywordNode **);

void SearchKeyword(struct KeywordNode *);

void MakeIndexFile(struct KeywordNode *);

void FreeHeap(struct KeywordNode *);

/*------------------------------------------------------------------*/

void main()

{

Init();

MakeKeywordList(&head);

SearchKeyword(head);

MakeIndexFile(head);

FreeHeap(head);

printf("The index file is available.");

}

/*------------------------------------------------------------------*/

void Init(void)

{

#ifdef DEFAULT

strcpy(scfile,"TAILIEU.TXT");

strcpy(kwfile,"TUKHOA.TXT");

strcpy(idfile,"CHISO.TXT");

#else

printf("Enter your source file: "); gets(scfile);

printf("Enter your keyword file: "); gets(kwfile);

printf("Enter your index file: "); gets(idfile);

#endif

}

82

Page 83: perl_5321

/*------------------------------------------------------------------*/

int GetPageNum(int lineNum)

{

return(lineNum/(LINES_PER_PAGE+1)+1);

}

/*------------------------------------------------------------------*/

void Standardlize(char *st)

{

int i,t,k;

// Remove unexpected spaces

t=0; k=0;

while(st[k]!='\0'){

while((st[k]==' ')&&(st[k+1]==' ')) k++;

st[t]=st[k];

t++;

k++;

}

st[t]='\0';

strlwr(st); // Not differ from lower and upper characters

}

/*------------------------------------------------------------------*/

void MakeKeywordList(struct KeywordNode **head)

{

struct KeywordNode *end,*newNode;

char keyword[MAX_KW_LEN];

char *ch; // Point to \n char of the keyword

kf=fopen(kwfile,"rt");

while(!feof(kf)){

fgets(keyword,MAX_KW_LEN,kf);

Standardlize(keyword);

ch=strchr(keyword,'\n'); *ch='\0'; // Delete \n char

newNode=MALLOC(struct KeywordNode);

if(newNode==NULL) break;

strcpy(newNode->keyword,keyword);

83

Page 84: perl_5321

newNode->firstRN=NULL;

newNode->lastRN=NULL;

if(*head==NULL) *head=newNode;

end->next=newNode;

end=newNode;

}

end->next=NULL;

fclose(kf);

}

/*------------------------------------------------------------------*/

void SearchKeyword(struct KeywordNode *head)

{

char bkLine[MAX_LINE_LEN]; // Backward Line = the first line

char fwLine[MAX_LINE_LEN]; // Forward Line = the second line

char pSt[MAX_LINE_LEN*2]; // Parsing String

int lineNum; // Line Number

int pageNum; // Page Number

struct KeywordNode *keyNode;

struct ResultNode *newNode;

lineNum=0;

sf=fopen(scfile,"rt");

bkLine[0]='\0';

while(!feof(sf)){

fgets(fwLine,MAX_LINE_LEN,sf);

strcpy(pSt,bkLine);

strcat(pSt,fwLine); // pSt=bkLine+fwLine

pSt[strlen(bkLine)-1]=' ';

Standardlize(pSt);

lineNum++;

for(keyNode=head;keyNode!=NULL;keyNode=keyNode->next)

if(strstr(pSt,keyNode->keyword)!=NULL){

pageNum=GetPageNum(lineNum);

if(keyNode->firstRN==NULL){

84

Page 85: perl_5321

newNode=(struct ResultNode *)malloc(sizeof(struct ResultNode));

if(!newNode){

fclose(sf);

return;

}

newNode->pageNum=pageNum;

newNode->next=NULL;

keyNode->firstRN=keyNode->lastRN=newNode;

}

else if(keyNode->lastRN->pageNum!=pageNum){

newNode=MALLOC(struct ResultNode);

if(!newNode){

fclose(sf);

return;

}

newNode->pageNum=pageNum;

newNode->next=NULL;

keyNode->lastRN->next=newNode;

keyNode->lastRN=newNode;

}

}

strcpy(bkLine,fwLine);

}

fclose(sf);

}

/*------------------------------------------------------------------*/

void MakeIndexFile(struct KeywordNode *head)

{

struct KeywordNode *keyNode;

struct ResultNode *reNode;

df=fopen(idfile,"wt");

for(keyNode=head;keyNode!=NULL;keyNode=keyNode->next){

if(keyNode->firstRN!=NULL) fprintf(df,"%s:",keyNode->keyword);

for(reNode=keyNode->firstRN;reNode!=NULL;reNode=reNode->next)

85

Page 86: perl_5321

if(reNode==keyNode->lastRN) fprintf(df,"%d\n",reNode->pageNum);

else fprintf(df,"%d,",reNode->pageNum);

}

fclose(df);

}

/*------------------------------------------------------------------*/

void FreeHeap(struct KeywordNode *head)

{

struct KeywordNode *ktemp;

struct ResultNode *rtemp1,*rtemp2;

for(ktemp=head;ktemp!=NULL;ktemp=head){

head=head->next;

for(rtemp1=ktemp->firstRN,rtemp2=rtemp1;rtemp2!=NULL;rtemp2=rtemp1){

rtemp1=rtemp1->next;

free(rtemp2);

}

free(ktemp);

}

}

86

Page 87: perl_5321

INDEX B - NHÚNG PERL VÀO TRONG C VÀ CẤP BỘ NHỚ ĐỘNG CHO PERL

1. Nhúng Perl vào trong C

1.1 Giới thiệu

Perl và C đều là những ngôn ngữ lập trình phổ biến. Mỗi ngôn ngữ có những điểm mạnh và điểm yếu riêng. C là một ngôn ngữ lập trình vạn năng, có tính thích nghi khả chuyển cao, cho phép can thiệp sâu vào hệ thống. Hơn nữa tốc độ biên dịch cũng như tốc độ chạy của các ứng dụng viết bằng C khá nhanh và ổn định. Trong khi Perl mặc dù chạy chậm hơn,nhưng lại rất mạnh ở xử lý văn bản, điều mà ngôn ngữ C không hỗ trợ nhiều. Hơn nữa 80% người bắt đầu học Perl đã từng làm quen với C hoặc C++. Chính vì thế việc kết hợp hai ngôn ngữ này trong một số điều kiện sẽ đem lại hiệu quả cao.

Tuy nhiên có một điều cần chú ý là việc nhúng Perl trong C và ngược lại chỉ thực hiện được trên LINUX(theo Perl 5 Unleashed). Và có thể cần dùng nhiều bộ nhớ hơn, và thỉnh thoảng làm chậm ứng dụng.

1.2 Chương trình mẫu

Một chương trình C có nhúng Perl phải gồm các hàm cơ bản như mẫu dưới đây:

Giải thích:

+ Dòng 1,2 : Để việc nhúng Perl trong C, trước hết ta cần gọi thêm 2 tệp header là EXTERN.h và perl.h . Cả 2 tệp này đều đi kèm theo bộ cài Perl

+ Dòng 3: Có thể có nhiều module viết bằng Perl (các Perl Interpreters) trong 1 chương trình C . Tất cả các trình thông dịch này đều được lưu trữ trong một cấu trúc gọi là PerlInterpreter. Trong chương trình trên dùng 1 trình thông dịch(interpreter), và được trỏ bởi con trỏ my_perl.

+ Dòng 5: khi thực hiện nhúng Perl thì trong hàm main của C bắt buộc phải có tham số argc, argv(tham số đầu tiên trong dòng lệnh trong UNIX hay DOS ), env.

+ Dòng 7: hàm perl_alloc() cấp phát bộ nhớ cho Perl Interpreter(điều này hay gặp khi ta dùng tới con trỏ). Ngược lại ở dòng 12, hàm perl_free() sẽ giải phóng bộ nhớ.

+ Dòng 8, hàm perl_construct() khởi đầu việc gọi trình thông dịch Perl và tất cả các cấu trúc dữ liệu liên quan. Dòng 11 kết thúc việc gọi trình thông dịch Perl bằng hàm perl_destruct()

87

Page 88: perl_5321

+ Dòng 10: Các chương trình Perl được đưa vào một bộ thông dịch, bộ thông dịch này chuyển đổi mã chương trình bạn viết thành mã byte(được thực hiện trước khi nó được chạy) và sau đó chạy nó. Hàm perl_run() sẽ khởi đầu việc này.

1.3 Ví dụ 1

Giả thiết rằng ta có đoạn script search.pl như sau:

Hàm search_files nhận 2 tham số là các xâu. Với thủ tục này, ta có 1 số cách để gọi nó trong chương trình C.

Chương trình ex.c sẽ gọi chương trình con search_files viết bằng Perl ở trên để tìm từ “struct” trong tất cả các file header của C.

Hãy chú ý dòng lệnh:perl_call_argv(“search_file”,G_DISCARD,my_argv);thay vì gọi perl_run, ta gọi search_file bằng hàm perl_call_argv(),và dùng G_DISCARD để loại bỏ tất cả các kết quả trả về. Ngoài ra còn có 1 số cách gọi chương trình Perl trong C nữa, chẳng hạn thay vì dùng hàm perl_call_argv() , ta có thể dùng:perl_call_va ("search_files",

"s", "struct", // First parameter of type string

"s", "*.h", // Second parameter also of type string

88

Page 89: perl_5321

NULL);

Để biên dịch chương trình trên ta gõ vào console của LINUX các lệnh sau:

% gcc -o ex -I/usr/local/lib/perl5/i586-linux/5.004/CORE \

-L/usr/local/lib/perl5/i586-linux/5.004/CORE \

-Dbool=char -DHAS_BOOL \

ex.c -lperl -lm

Kết quả thu được có dạng sau:

av.h[10]: struct xpvav {

cop.h[58]: struct cop {

cop.h[60]: char * cop_label; /* label for this construct */

cop.h[75]: struct block_sub {

cop.h[98]: { struct block_sub cxsub;

...

Cách biên dịch trên có vẻ phức tạp và khó nhớ. Để thuận tiện cho việc nhúng Perl vào trong C, ta sử dụng 1 module chuyên hỗ trợ việc này. Đó là ExtUtils::Embed . Với chương trình ex.c ta sẽ biên dịch nó như sau:

% cc -c xsinit.c `perl -MExtUtils::Embed -e ccopts`

% cc -c ex.c `perl -MExtUtils::Embed -e ccopts`

% cc -o ex ex.o xsinit.o `perl -MExtUtils::Embed -e ldopts

Dùng -M chính là để gọi ExtUtils::Embed (giống như trong Pascal dùng uses ExtUtils::Embed;). xsinit.c là file được tạo ra từ lời gọi trên. File này cũng tạo ra hàm xs_init .

Hoặc ta có thể gõ như sau:

% cc -o ex ex.c `perl -MExtUtils::Embed -e ccopts -e ldopts`

% ex search.pl

1.4 Ví Dụ 2 :

Giả sử ta viết 1 chương trình Perl là showtime.pl

sub showtime {

print time;

89

Page 90: perl_5321

}

Còn chương trình showtime.c gọi chương trình con showtime ở trên như sau:

#include <EXTERN.h>

#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env)

{

char *args[] = { NULL };

my_perl = perl_alloc();

perl_construct(my_perl);

perl_parse(my_perl, NULL, argc, argv, NULL);

/*** skipping perl_run() ***/

call_argv("showtime", G_DISCARD | G_NOARGS, args);

perl_destruct(my_perl);

perl_free(my_perl);

}

Để chạy chương trình trên ta gõ trong console của LINUX các dòng lệnh sau:

% cc -o showtime showtime.c `perl -MExtUtils::Embed -e ccopts -e ldopts`

% showtime showtime.pl

Một ví dụ nổi tiếng nhất về embedding Perl in C là module mod_perl của Apache. Nhưng vì thời gian không cho phép, chúng em chưa đưa vào được.

2. Bộ nhớ động

Theo các tài liệu chúng em đã tham khảo, không thấy Perl hỗ trợ việc sử dụng bộ nhớ động. Tuy nhiên như phần đã trình bày ở trên, có thể cấp phát bộ nhớ động cho Perl thông qua việc sử dụng con trỏ và bộ nhớ động của C.

90

Page 91: perl_5321

91

Page 92: perl_5321

INDEX C: VÀI NÉT VỀ PHP TRÊN CƠ SỞ PERL

Giới thiệu

Mặc dù PHP không có nhiều công cụ như Perl song nó có nhiều phần rất hay. Sau đây

là bài so sánh một số hàm và công cụ trong Perl với PHP.

1. Mảng

- List và Hash: + PHP không phân biệt list và hash như Perl

+ Mọi loại biến trong PHP đều bắt đầu bởi $, so với Perl: biến vô hướng

bắt đầu bởi $, @ cho list và % cho Hash

- Toán tử exits: Để kiểm tra sự tồn tại của một khóa Hash trong PHP, ta dùng in_array

- map: array_walk = chunk of code execute

2. Biến

- delete -> unset

- reset: thường sử dụng trong PHP, dùng để trở về phần tử đầu tiên cuả mảng

- undef -> unset

3. Đối sánh:

s// -> dùng preg_replace

m// -> dùng preg_match

tr// -> strtr

4. Xâu:

- chomp ->trim, ltrim

- chop -> không có toán tử tương tự chop trong PHP, bạn phải viết một CT con dùng substr

- lc,uc -> strtolower, strtoupper

- lcfirst, ucfirst -> không có toán tử tương tự lcfirst. Tuy nhiên có toán tử tương tự ucfirst, đó là ucwords

- quotemeta ->quotemeta, addslashes, htmlentities, htmlspecialchars

92

Page 93: perl_5321

- q, qq, qw, qx: Không có trong PHP

- ge, gt, le, lt, ne: không cần thiết trong PHP, ta có thể sử dụng cùng toán tử so sánh cho số và xâu

- repeating a string: Ví dụ: trong perl ta có thể dùng lệnh print "-"x20, nhưng trong PHP,

ta phải dùng CT con str_repeat (Chỉ có ở PHP4 về sau)

5. Các lệnh điều khiển:

- do <câu lệnh> if (<biểu thức điều kiện>): Không có trong PHP

Trong PHP chỉ dùng cú pháp: if (<biểu thức điều kiện>) do <câu lệnh>

- do..until: Cơ bản 2 ngông ngữ là giống nhau

- elsif-> elseif

- foreach: chỉ có ở PHP4 về sau

- goto: Do PHP không sử dụng nhãn (label), cho nên nó không dùng goto

- last->break

- next-> continue

- sub->return, trong Perl, sub dùng để xác định một hàm

- switch, case: PHP có switch

- unless: không có trong PHP, ta phải dùng lệnh if

6. Các biểu thức toán học:

- Lũy thừa: trong Perl, ta có 2^3, trong PHP, ta phải dùng hàm pow

- hex->hexdec

- rand, srand: cũng có trong PHP, tuy nhiên dùng các toán tử mt_rand, mt_srand thì tốt hơn

7. Tệp:

- Để đọc một tệp vào mảng, Perl dùng câu lệnh: @array=<FILEHANDLE>, trong PHP, ta dùng file

- eof->feof

- link->symlink

- open, close->fopen, fclose

PHP còn có một số hàm khác tương tự như Perl, tuy nhiên chúng bắt đầu bằng f: ftell, fseek va fstat

- print FILEHANHDLE->dùng fputs hay fwrite

- socket connections: chỉ có trong Perl4 về sau

- sysread->fread

93

Page 94: perl_5321

8. Các vấn đề khác:

- Định dạng: PHP không có các chuẩn định dạng như Perl

- localtime: không phức tạp như hàm localtime của Perl, PHP dùng hàm gettimeofday. Tuy nhiên, PHP4 trở về sau có hàm localtime

94

Page 95: perl_5321

TÀI LIỆU THAM KHẢO

1. Teach Yourself Perl 5 in 21 days David Till & Kamran Husain

2. Perl 5 UNLEASHED by Kamran Husain and Robert F. Breedlove

3. http://www.unix.org.ua/orelly/perl/

4. http://www.linuxuser.co.uk/articles/issue25

5. Extending and Embedding Perl Tim Jenness

6. Perl 5 by Example by David Medinets

7. PERL Quick Reference by Micheál ó Foghlú

8. Learning Perl by Schwartz, R.L. 1993.

9. www.cclabs.missouri.edu/things/instruction/perl

10. http://archive.ncsa.uiuc.edu/General/Training/PerlIntro/

11. A Perl Tutoral Modified from: Nano Gough

http://www.computing.dcu.ie/~ngough/perl/tutorial.ppt

12. http://www.rahji.com/perlphp.php3

13. http://www.cs.cf.ac.uk

14. http://www.perl.com/language/faq/

15. http://www.ebb.org/PickingUpPerl

95

Page 96: perl_5321

16. Programming Perl (2nd edition). Wall, L., Christiansen, T. and Schwartz, R.L. 1996

17. Ngôn ngữ lập trình Perl cho người mới học – Biên dịch: TS Lê Minh Trung, Quốc Bình – NXB Thống Kê 2002

96