Ngôn ngữ Perl-Chương 01-Giới thiệu

21 264 0
Ngôn ngữ Perl-Chương 01-Giới thiệu

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Learning Perl - Chương 1: Giới thiệu qua về Perl 1. Lịch sử của Perl 2. Mục đích của Perl 3. Tính sẵn có 4. Hỗ trợ (nếu có khúc mắc) 5. Các khái niệm căn bản 6. Sơ qua về Perl 7. Bài tập 1.1 Lịch sử Perl PERL là cách viết tắt cho “Practical Extraction and Report Language”, mặc dù còn được gọi là “Pathologically Eclectic Rubbish Lister". Larry Wall đã tạo ra Perl khi cố gắng sản xuất ra một số báo cáo từ một cấp bậc các tệp kiểu như thư người dùng mạng Usenet về hệ thống báo lỗi, và lệnh awk và đưa ra bản đầu tiên của Perl. Sau đó Larry đưa nó cho các độc giả Usenet, thường vẫn được gọi là “the Net”. Kết quả là Perl phát triển dần và cũng cùng tỉ lệ như kernel của UNIX. Nó đã phát triển các tính năng và tính khả chuyển. Larry sẽ đưa ra bản Perl mới nhất, bản 5.0, chắc chắn sẽ có một số tính năng thường hay được yêu cầu, và được thiết kế lại từ bên trong trở ra. Tuy nhiên, cuốn sách này đã được thử với Perl bản 4.0. Mọi thứ ở đây đều sẽ làm việc với bản 5.0 và các bản sau của Perl. Trong thực tế, chương trình Perl 1.0 vẫn làm việc tốt với những bản gần đây, ngoại trừ một vài thay đổi khác cần cho sự nâng cấp. 1.2 Mục đích của Perl Perl được thiết kế để trợ giúp cho người dùng UNIX với những nhiệm vụ thông dụng mà có thể rất nhậy cảm với tính khả chuyển đối với trình shell, vì nó ngắn hơn và không phức tạp như các ngôn ngữ lập trinh C hay một ngôn ngữ công cụ UNIX nào khác. Khi đã quen thuộc với Perl, bạn sẽ mất ít thời gian để lấy được các trích dẫn dòng lệnh shell (hay khai báo C), và mất ít thời gian để lập trình vì Perl là một công cụ trợ giúp tuyệt vời. Các cấu trúc chặt chẽ của Perl cho phép tạo ra một số giải pháp với những công cụ mang tính tổng quát. Cũng vậy, bạn có thể lấy những công cụ này sang công việc tiếp, vì Perl có tính khả chuyển cao và lại có sẵn trên hầu hết các hệ thống. Giống như mọi ngôn ngữ khác, Perl có thể “chỉ viết” - tức là có thể viết ra chương trình cho máy hiểu mà con người không thể "đọc hiểu" được. Nhưng nếu chú ý cẩn thận, bạn có thể tránh được điều này. Thật vậy, đôi khi Perl trông như khó với những ai không quen, nhưng với người lập trình đã thạo Perl, nó cũng . khá dễ (???). Nếu bạn làm theo những hướng dẫn trong cuốn sách này thì chương trình của bạn sẽ dễ đọc, dễ bảo trì và nâng cấp. 1.3 Tính sẵn có Nếu bạn nhận được một lỗi nhỏ: Perl: not found khi bạn thử gọi Perl từ dòng lệnh shell thì điều đó có nghĩa là Perl chưa được cài đặt trên hệ thống của bạn. Nhưng bạn hoàn toàn có thể lấy được Perl miễn phí vài cài vào hệ thốgn của mình. Perl được phân phối theo Giấy phép Công cộng GNU (GNU Public License), nghĩa là bạn có thể phân phát bản binary của Perl với điều kiện là phải kèm theo mã ngồn miễn phí; và nếu bạn sửa đổi Perl thep ý bạn bạn cũng phải phân phối mã nguồn của phần mà bạn sửa đổi. Bạn có thể lấy mã nguồn của Perl hoàn toàn miễn phí qua đường download mà chỉ tốn vài MB để lưu trữ và một khoảng thời gian để tải xuống. Trong thực tế, nó không chỉ là miễn phí mà nó chạy còn gọn hơn trên gần như mọi thứ mà có thể gọi là UNIX hay tựa UNIX và có trình biên dịch C. Đó là vì là Perl có 1 phần được gọi là "Cấu hình" sẽ có nhiệm vụ gọi vào các danh mục hệ thống để tìm những thứ nó cần, và điều chỉnh việc đưa vào các tệp và các kí hiệu được xác định tương ứng, và cuối cùng nó sẽ chuyển cho bạn việc kiểm chứng phát hiện của nó. Bên cạnh các hệ thống UNIX hay tựa UNIX, các "tín đồ" của Perl đã đem nó sang Amiga, Atari ST, họ Macintosh, VMS, OS/2, thậm chí MS/DOS, Windows - và có lẽ còn nhiều hơn nữa khi bạn đang đọc những dòng chữ này. Vị trí chính xác và sự có sẵn của những bản Perl này thì biến động, cho nên phải hỏi trên nhóm tin Usenet chẳng hạn để có được thông tin mới nhất. Nếu bạn là một newbie, thì một bản cũ của Perl đã có trên đĩa phần mềm CD-ROM UNIX Power Tools, của Jerry Peek, Tim O’Reilly và Mike Loukides (O’Reilly & Associates/ Random House Co., 1993), hoặc bạn có thể tìm và download ở http://www.perl.org/. 1.4 Hỗ trợ (nếu như có khúc mắc) Bạ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 perl-users- request@virgina.edu. Bên cạnh nhóm tin, bạn cũng nên đọc tạp chí Perl, đi cùng việc phân phối Perl. Một nguồn có thẩm quyền khác là cuốn sách Programming Perl của Larry Wall và Randal L. Schwatrz (O’Reilly & Associaté, 1990). 1.5 Các khái niệm cơ bản về Perl Một kịch bản shell là một dãy các lệnh shell đưa vào trong một tệp văn bản. Tệp này chạy bằng cách bật một bit thực hiện (qua chmod +x filename) rồi gõ tên của tệp đó tại dấu nhắc của shell. Chẳng hạn, một kịch bản shell để chạy lệnh date và sau đó là lệnh who sẽ được viết như sau: $ echo date > somecript $ echo who >> somecript $ cat somescript date who $ chmod +x somescript $ somescript [output of date followed by who] $ Tương tự, một chương trình Perl là một bó các câu lệnh và định nghĩa Perl được đưa vào trong một tệp. Rồi bạn bật bit thực hiện và gõ tên của tệp này tại lời nhắc của vỏ. Tuy nhiên, tệp này phải chỉ ra rằng đây là một chương trình Perl và không phải là chương trình shell, nên chúng ta cần một bước phụ: đặt #!/usr/bin/perl làm dòng đầu tiên của tệp này. Nhưng nếu Perl của bạn được cài vào nơi không chuẩn (không phải là /usr/bin), hay hệ thống tựa UNIX của bạn không hiểu dòng #!, thì .bạn hỏi người quản trị hệ thống của bạn để được giúp đỡ. Các thí dụ trong sách này giả sử rằng hệ thống của bạn đã được cài đặt Perl vào /usr/bin. Perl là một ngôn ngữ phi định dạng kiểu như C - khoảng trắng giữa các phần tử của chương trình là tuỳ chọn, trừ phi hai phần tử của chương trình dính liền với nhau có thể bị lầm lẫn thành một cái khác, trong trường hợp đó thì khoảng trắng thuộc loại nào đó là bắt buộc (Khoảng trắng bao gồm dấu cách, dấu tab, xuống dòng, về đầu dòng hay sang trang mới). Có một vài cấu trúc đòi hỏi một loại khoảng trắng nào đó ở chỗ nào đó, nhưng đừng lo, tài liệu sẽ chỉ rõ cho bạn biết là các khoảng trắng phải được đặt như thế nào với số lượng bao nhiêu. Có thể giả thiết rằng loại và số lượng khoảng trắng giữa các phần tử trong chương trình là tuỳ ý trong các trường hợp khác. Mặc dù gần như tất cả các chương trình Perl đều có thể được viết tất cả trên một dòng, nhưng một chương trình Perl điển hình được viết xuống dòng và canh lề như chương trình C, với những phần câu lệnh lồng nhau được viết vào sâu hơn một chút chẳng hạn, sẽ làm cho chương trình của bạn dễ nhìn và dễ hiểu hơn. Cũng giống như một kịch bản shell, 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ề hàm chính main như trong C. Chú thích của Perl giống như chú thích của kịch bản shell: bất kì cái gì nằm giữa một dấu # tới cuối dòng đều là một chú thích. Perl không có chú thích trên nhiều dòng như C. Không giống hầu hết các shell (nhưng giống như awk và sed), bộ thông dịch Perl phân tích và biên dịch hoàn toàn chương trình trước khi thực hiện nó. Điều này có nghĩa là bạn không bao giờ nhận được lỗi cú pháp từ chương trình một khi chương trình đã bắt đầu chạy, và cũng có nghĩa là khoảng trắng và chú thích sẽ được lược bỏ mất và sẽ không làm chậm chương trình. Trong thực tế, giai đoạn biên dịch này bảo đảm việc thực hiện nhanh chóng của các thao tác Perl một khi nó được bắt đầu, và nó cung cấp động cơ phụ để loại bỏ C như một ngôn ngữ tiện ích hệ thống nhất đơn thuần dựa trên nền tảng là C được coi là trình biên dịch. Việc biên dịch này khá tiêu tốn thời gian. Và sẽ là phi hiệu quả nếu một chương trình Perl lớn lại chỉ thực hiện một nhiệm vụ nhỏ bé (trong số nhiều nhiệm vụ tiềm năng) và rồi thoát, vì thời gian chạy cho chương trình sẽ "nhỏ xíu" nếu so với thời gian biên dịch. Cho nên Perl giống như một bộ biên dịch và thông dịch. Nó là biên dịch vì chương trình được đọc và phân tích hoàn toàn trước khi câu lệnh đầu tiên được thực hiện. Nó là bộ thông dịch vì không có mã đích chiếm không gian đĩa. Hiểu theo một cách nào đó, nó là tốt nhất cho cả hai loại này. 1.6 Sơ lược về Perl Sau đây sẽ giới thiệu một số các tính năng khác nhau bằng cách bổ sung vào một ứng dụng nhỏ. Giải thích ở đây ngắn gọn - mỗi vùng chủ đề đều được thảo luận chi tiết hơn nhiều về sau trong cuốn sách này. Nhưng việc "xem qua" này sẽ cho bạn kinh nghiệm nhanh chóng về ngôn ngữ. • 1.6.1 Chương trình “Hello” Ta hãy nhìn vào một chương trình nhỏ sau: #!/usr/bin/perl print "Hello!\n"; Dòng đầu tiên báo đây là chương trình Perl. Nó cũng là lời chú thích cho Perl cho tới cuối dòng, giống như hầu hết các kịch bản shell hay awk. 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. Hàm print bắt đầu chương trình, và nó có một đối số là một xâu văn bản kiểu C. Bên trong xâu này, tổ hợp kí tự \n biểu thị cho kí tự dòng mới. Giống như trong C, tất cả các câu lệnh đơn giản đều kết thúc bằng dấu chấm phảy (;). Khi bạn gọi chương trình này, phần kernel sẽ gọi bộ thông dịch Perl, phân tích toàn bộ chương trình (hai dòng, kể cả dòng chú thích đầu tiên) và thực hiện dạng đã dịch. Thao tác đầu tiên và duy nhất là thực hiện hàm print. Sau khi chương trình đã hoàn tất, thì tiến trình Perl sẽ trả về một mã cho shell để báo rằng chương trình đã kết thúc. • 1.6.2 Hỏi câu hỏi và nhớ kết quả Ta hãy viết lại chương trình ở trên một chút, thay vì Hello trống không, chương trình sẽ chào tên người nhập vào từ bàn phím. Để làm việc này, ta cần một chỗ lưu giữ tên, một cách hỏi tên, và một cách nhận câu trả lời. Để đặt chỗ giữ giá trị (VD: tên) ta dùng biến vô hướng. Với chương trình này, ta sẽ dùng biến vô hướng $name để giữ tên (xem chi tiết trong chương sau: Dữ liệu vô hướng, về những gì mà biến này có thể giữ, và những gì có thể làm với chúng). Bây giờ, giả sử rằng bạn có thể giữ một số hay một xâu (dãy các kí tự) trong biến vô hướng. Chương trình này cần hỏi về tên. Để làm điều đó, ta cần một cách nhắc và một cách nhận vào. Chương trình trước đã chỉ ra cho ta cách nhắc - dùng hàm print. Và để nhận một dòng từ thiết bị cuối ta dùng toán tử <STDIN>. Ta dữ liệu nhập vào cho biến $name: print "Ten ban la gi? "; $name = <STDIN>; Giá trị của $name tại điểm này có một ký tự xuống dòng ở cuối (vì bạn phải nhấn Enter để kết thúc việc nhập tên). Để bỏ qua kí tự đó, chúng ta dùng hàm chop(). Hàm này lấy một biến vô hướng làm đối số duy nhất và bỏ đi ký tự cuối từ giá trị xâu của biến: chop($name); Sau đó in ra câu chào: print "Xin chao ban $name"; Và ta có chương trình hoàn chỉnh: #!/usr/bin/perl print "Ten ban la gi? "; $name = <STDIN>; chop($name); print "Xin chao ban $name!\n"; • 1.6.3 Bổ sung chọn lựa Bây giờ ta muốn có một lời chào đặc biệt cho Jenny, nhưng muốn lời chào thông thường cho mọi người khác. Để làm điều này, ta cần so sánh tên đã được đưa vào với xâu Jenny, và nếu hai xâu trùng khớp, thì làm điều gì đó đặc biệt. Ta hãy bổ sung thêm lệnh if-then-else và phép so sánh vào chương trình: #!/usr/bin/perl print "Ten ban la gi? "; $name = <STDIN>; chop($name); if ($name eq "Jenny") { #chao Jenny print "Chao Jenny! Lam bai tap di chu!\n"; } else { #chao binh thuong print "Xin chao ban $name!\n"; } Toán tử eq so sánh hai xâu. Nếu bằng nhau (từng kí tự một, và có cùng chiều dài) kết quả sẽ là True, ngược lại sẽ là False. Câu lệnh if chọn xem "khối" câu lệnh nào so sánh đúng được thực hiện - nếu biểu thức ($name eq "Jenny") là True, khối chưa câu lệnh print "Chao Jenny! Lam bai tap di chu!\n"; sẽ được thực hiện, còn trong trường hợp ngược lại sẽ là khối chưa câu lệnh print "Xin chao ban $name!\n";. • 1.6.4 Đoán từ bí mật Để một người chạy chương trình đoán một từ bí mật. Với mọi người trừ Jenny, ta hãy để cho cho chương trình cứ hỏi lặp lại để đoán đến khi nào người này đoán được đúng. Hãy xem chương trình sau: #!/usr/bin/perl $secretword = "Jenny"; #tu bi mat print "Ten ban la gi? "; $name = <STDIN>; chop($name); if ($name eq "Jenny") { print "Chao Jenny! Lam bai tap di chu!\n"; } else { print "Xin chao ban $name!\n"; print "Ban thu doan xem toi ten la gi? "; $guess = <STDIN>; chop($guess); while ($guess ne $secretword) { print "Sai roi, doan lai di"; $guess = <STDIN>; chop($guess); } } Trước hết, ta định nghĩa tên cần đoán bằng việc đặt nó vào trong biến vô hướng khác, $secretword. Sau khi đón chào, một người (không phải Jenny) sẽ được yêu cầu (với một câu lệnh print khác) đoán chữ. Lời đoán được đem ra so sánh với từ cần đoán bằng việc dùng toán tử ne, mà sẽ cho True nếu các xâu này không bằng nhau (ne là toán tử ngược với toán tử eq). Kết quả của việc so sánh sẽ kiểm soát while, chu trình này thực hiện khi việc so sánh vẫn còn True. • 1.6.5 Nhiều từ bí mật Ta hãy xem cách thức mình có thể sửa đổi đoạn chương trình này để cho phép có nhiều từ bí mật. Bằng việc dùng điều ta đã thấy, chúng ta có thể so sánh lời đoán lặp đi lặp lại theo một chuỗi câu trả lời rõ được cất giữ trong các biến vô hướng tách biệt. Tuy nhiên, một danh sách như vậy sẽ khó mà thay đổi hay đọc vào từ một tệp hay thiết bị khác. Một giải pháp tốt hơn là cất giữ tất cả các câu trả lời có thể vào trong một cấu trúc dữ liệu gọi là danh sách hay mảng. Mỗi phần tử của mảng đều là một biến vô hướng tách biệt mà có thể được đặt giá trị hay truy cập độc lập. Toàn bộ mảng cũng có thể được trao cho một giá trị để ta có thể "truy nhập" vào. Ta có thể gán một giá trị cho toàn bộ mảng có tên @words sao cho nó chứa ba mật hiệu: @words =("littlecat", "smalldog", "bigmouse"); Tên biến mảng bắt đầu với @, cho nên chúng là khác biệt với các tên biến vô hướng. Một khi mảng đã được gán thì ta có thể truy cập đến từng phần tử bằng cách dùng một tham khảo chỉ số. Cho nên $words[0] là littlecat, $words[1] là smalldog, $words[2] là bigmouse. Chỉ số cũng có thể là một biểu thức, cho nên nếu ta đặt $i là 2 thì $words[$i] là bigmouse. (Tham khảo chỉ số bắt đầu với $ thay vì @ là do chúng tham khảo tới một phần tử riêng của mảng thay vì toàn bộ mảng). Quay trở lại với thí dụ trước đây của ta: #!/usr/bin/perl #cac tu bi mat @words = ("littlecat", "smalldog", "bigmouse"); print "Ten ban la gi? "; $name = <STDIN>; chop($name); if ($name eq "Jenny") { print "Chao Jenny! Lam bai tap di chu!\n"; } else { print "Xin chao ban $name!\n"; print "Tu bi mat la gi"; $guess = <STDIN>; chop($guess); $i = 0; #thu truoc 1 tu $correct = "co the"; #tu nay co doan dung hay khong? while ($correct eq "co the") { #cu kiem tra den khi het if ($words[$i] eq $guess) { $correct = "co"; #dung roi } elsif ($i < 2) { $i = $i + 1; #xet tu tiep theo } else { print "Sai roi, thu lai di. Tu bi mat ma gi? "; $guess = <STDIN>; chop($guess); $i = 0; #kiem tra lai tu dau 1 lan nua } } #key thuc cua while ($correct eq "co the") } #Ket thuc cua "not Jenny" Chú ý rằng chúng ta đang dùng biến vô hướng $correct để chỉ ra rằng chúng ta vẫn đang tìm ra mật hiệu đúng, hoặc chúng ta không tìm thấy. Chương trình này cũng giới thiệu khối elsif của câu lệnh if-then-else. Không có lệnh nào tương đương như thế trong C hay awk - đó là việc viết tắt của else và theo sau là một if mới nhưng không lồng trong cặp dấu () khác. Đây chính là cái rất giống Perl để so sánh một tập các điều kiện trong việc phân tầng if-elsif-elsif-elsif- else. • 1.6.6 Cho mỗi người một từ bí mật khác nhau Trong chương trình trước, bất kì người nào tới cũng đều có thể đoán bất kì từ nào trong ba từ này và có thể thành công. Nếu ta muốn từ bí mật là khác nhau cho mỗi người, thì ta cần một bảng so sánh giữa người và từ: Người Từ bí mật Chip littlecat Dale smalldog Tom bigmouse Jerry bigmouse Chú ý rằng Jerry và Tom có chung từ bí mật là bigmouse; điều này hoàn toàn hợp lệ. Cách dễ nhất để cất giữ một bảng như thế trong Perl là bằng một "mảng băm" (hash array). Mỗi phần tử của mảng này giữ một giá trị vô hướng tách biệt (giống như kiểu mảng khác), nhưng các mảng lại được tham khảo theo khoá, có thể là bất kì giá trị vô hướng nào (bất kì xâu hay số, kể cả số không nguyên và giá trị âm). Để tạo ra một mảng băm %words (chú ý % không phải là @) với khoá và giá trị được cho trong bảng trên, ta gán một giá trị cho %words (như ta đã làm nhiều trước đây với mảng khác): %words = ( "Chip" , "littlecat", "Dale" , "smalldog", "Tom" , "bigmouse", "Jerry", "bigmouse" ); Mỗi cặp giá trị trong danh sách đều biểu thị cho một khoá và giá trị tương ứng của nó trong mảng băm. Chú ý rằng ta đã chia phép gán này ra 4 dòng mà không có bất kì loại kí tự nối dòng nào, vì khoảng trắng giữa các phần tử chương trình nói chung là vô nghĩa trong Perl. Để tìm ra từ bí mật cho Tom, ta cần dùng Tom như khoá trong một tham khảo vào mảng kết hợp %words, qua một biểu thức nào đó như $words{"Tom"}. Giá trị của tham khảo này là bigmouse, tương tự như điều ta đã làm trước đây với mảng khác. Cũng như trước đây, khoá có thể là bất kì biểu thức nào, cho nên gán $person bằng Tom và $words{$person} cũng sẽ trả về giá trị bigmouse. Chương trình hoàn chỉnh như sau: #!/usr/bin/perl %words = ( "Chip" , "littlecat", "Dale" , "smalldog", "Tom" , "bigmouse", "Jerry", "bigmouse" ); print "Ten ban la gi? "; $name = <STDIN>; chop($name); if ($name eq "Jenny") { print "Chao Jenny! Lam bai tap di chu!\n"; } else { print "Xin chao ban $name!\n"; #chao thuong thuong $secretword = $words{$name}; #lay tu bi mat print "Tu bi mat la gi? "; $guess = <STDIN>; chop($guess); while ($correct ne $secretword) { print "Sai roi thu lai di. Tu bi mat la gi? "; $guess = <STDIN>; chop($guess); } #ket thuc cua while } Bạn hãy chú ý nhìn vào từ bí mật. Nếu không tìm thấy từ này thì giá trị của $secretword sẽ là một xâu rỗng, mà ta có thể kiểm tra liệu ta có muốn xác định một từ bí mật mặc định cho ai đó khác không. Đây là cách xem nó: # $secretword = $words{$name}; #lay tu bi mat if ($secretword eq "") { #khong thay $secretword = "none"; } print "Tu bi mat la gi?"; # • 1.6.7 Giải quyết định dạng đầu vào thay đổi Nếu đưa vào Jenny L. Schwartz hay jenny thay vì Jenny thì chương trình sẽ không đưa ra kết quả như mong đợi. Vì toán tử so sánh eq thì lại so sánh đúng sự bằng nhau của từng ký tự một. Ta hãy xem một cách giải quyết cho điều đó. Giả sử tôi muốn tìm bất kì xâu nào bắt đầu với Jenny, thay vì chỉ là một xâu bằng Jenny. Tôi có thể làm điều này trong sed hay awk hoặc grep với một biểu thức chính qui-một tiêu bản sẽ xác định ra một tập hợp các xâu sánh đúng. Giống như trong sed hay grep, biểu thức chính qui trong Perl để sánh bất kì xâu nào bắt đầu với Jenny là ^Jenny. Để sánh xâu này với xâu trong $name, chúng ta dùng toán tử so sánh như sau: if ($name =~ /^Jenny/) { ## yes - True } else { ## no - False } Chú ý rằng biểu thức chính qui được định biên bởi dấu sổ chéo (/). Bên trong các dấu sổ chéo thì các dấu cách và khoảng trắng là có nghĩa, hệt như chúng ở bên trong xâu. Nhưng chúng ta vẫn chưa giải quyết việc lựa chọn jenny hay loại bỏ Jennyy. Để chấp nhận jenny, chúng ta thêm tuỳ chọn bỏ qua không xét chữ hoa và chữ thường, một chữ i nhỏ được thêm vào sau dấu sổ chéo thứ hai. Để loại bỏ Jennyy, ta thêm một đánh dấu đặc biệt định biên từ (tương tự với vi và một số bản của grep) dưới dạng \b trong biểu thức chính qui. Điều này đảm bảo rằng kí tự đi sau chữ y đầu tiên trong biểu thức chính qui không phải là một kí tự a,b,c khác. Điều này làm thay đổi biểu thức chính qui thành /^jenny\b/i, có nghĩa là "jenny tại đầu xâu, không có kí tự hay chữ số nào theo sau, và chấp nhận cả hai kiểu chữ hoa thường". Ta có chương trình như sau: #!/usr/bin/perl %words = ( "Chip" , "littlecat", "Dale" , "smalldog", "Tom" , "bigmouse", "Jerry", "bigmouse" ); print "Ten ban la gi? "; $name = <STDIN>; chop($name); if ($name =~ /^jenny\b/i) { print "Chao Jenny! Lam bai tap di chu!\n"; } else { print "Xin chao ban $name!\n"; #chao thuong thuong $secretword = $words{$name}; #lay tu bi mat if ($secretword eq "") { #khong thay $secretword = "none"; } print "Tu bi mat la gi? "; $guess = <STDIN>; chop($guess); while ($correct ne $secretword) { print "Sai roi thu lai di. TU bi mat la gi? "; $guess = <STDIN>; chop($guess); } #ket thuc cua while } Như bạn có thể thấy, chương trình này khác xa với chương trình đơn giản lúc đầu nhưng nó vẫn còn rất nhỏ bé và làm việc được. Perl đưa ra tính năng về các biểu thức chính qui có trong mọi trình tiện ích UNIX chuẩn (và thậm chí trong một số không chuẩn mấy vẫn được). Không chỉ có thế, cách thức Perl giải quyết cho việc so sánh xâu là cách nhanh nhất trên hành tinh nay (Một chương trình giống như grep được viết trong Perl thường tốt hơn nhiều so với chương trình grep được các nhà cung cấp viết trong C với hầu hết các dữ liệu vào). • 1.6.8 Làm cho công bằng với mọi người Vậy bây giờ tôi có thể đưa vào Jenny hay jenny hoặc Jenny L. Schwartz, nhưng với những người khác thì sao? Tom vẫn phải nói đúng là Tom (thậm chí không được có Tom với một dấu cách theo sau). Để công bằng cho Tom (và cho những người khác), chúng ta cần nắm được từ đầu của bất kì cái gì được đưa vào, và chuyển nó thành chữ thường trước khi ta tra tên trong bảng. Ta làm điều này bằng hai toán tử: toán tử thay thế sẽ tìm ra một biểu thức chính qui và thay thế nó bằng một xâu; và toán tử hoán chuyển để chuyển toàn bộ này thành chữ thường. Trước hết, toán tử thay thế: chúng ta muốn lấy nội dung của $name, tìm kí tự đầu tiên không là từ, và loại đi mọi thứ từ đây cho đến cuối xâu. /\W.*/ là một biểu thức chính qui mà ta đang tìm kiếm: \W viết tắt cho kí tự không phải là từ (một cái gì đó không phải là chữ, chữ số hay gạch dưới) và .* có nghĩa là bất kì kí tự nào từ đấy tới cuối dòng. Bây giờ, để loại những kí tự này đi, ta cần lấy bất kì bộ phận nào của xâu sánh đúng với biểu thức chính qui này và thay nó với cái không có gì: $name =~ s/\W.*//; Chúng ta đang dùng cùng toán tử =~ mà ta đã dùng trước đó, nhưng bây giờ bên vế phải ta có toán tử thay thế: chữ s được theo sau bởi một biểu thức chính qui và xâu được định biên bởi dấu sổ chéo. (Xâu trong thí dụ này là xâu rỗng giữa dấu sổ chéo thứ hai và thứ ba). Toán tử này trông giống và hành động rất giống như phép thay thế của các trình soạn thảo khác nhau. Bây giờ để có được bất kì cái gì còn lại trở thành chữ thường thì ta phải dịch xâu này dùng toán tử tr. Nó trông rất giống chỉ lệnh tr của UNIX: nhận một danh sách các kí tự để tìm và một danh sách các kí tự để thay thế chúng. Với thí dụ của ta, để đặt nội dung của $name thành chữ thường, ta dùng: $name =~ tr/A-Z/a-z/; Các dấu sổ chéo phân cách các danh sách kí tự cần tìm và cần thay thế. Dấu gạch ngang giữa A và Z thay thế cho tất cả các kí tự nằm giữa, cho nên chúng ta có hai danh sách, mỗi danh sách có 26 kí tự. Khi toán tử tr tìm thấy một kí tự từ một xâu trong danh sách thứ nhất thì kí tự đó sẽ được thay thế bằng kí tự tương ứng trong danh sách thứ hai. Cho nên tất cả các chữ hoa A trở thành chữ thường a, B trở thành b và cứ như thế. Ta có chương trình hoàn chỉnh: #!/usr/bin/perl %words = ( "Chip" , "littlecat", "Dale" , "smalldog", "Tom" , "bigmouse", "Jerry", "bigmouse" ); print "Ten ban la gi? "; $name = <STDIN>; chop($name); $original_name = $name; #cat giu de chao mung $name =~ s/\W.*//; #bo moi thu sau tu dau tien $name =~ tr/A-Z/a-z/; #chuyen thanh chu thuong if ($name eq "jenny") { print "Chao Jenny! Lam bai tap di chu!\n"; } else { print "Xin chao ban $original_name!\n"; #chao thuong thuong $secretword = $words{$name}; #lay tu bi mat if ($secretword eq "") { #khong thay $secretword = "none"; } print "Tu bi mat la gi? "; $guess = <STDIN>; chop($guess); while ($correct ne $secretwords) { print "Sai roi thu lai di. Tu bi mat la gi? "; $guess = <STDIN>; chop($guess); } #ket thuc cua while } Bạn hãy để ý đến cách thức biểu thức chính qui sánh đúng với tên Jenny đã lại trở thành việc so sánh đơn giản (dùng eq). Sau rốt, cả Jenny L. Schwartz và Jenny đều trở thành jenny sau khi . với trình shell, vì nó ngắn hơn và không phức tạp như các ngôn ngữ lập trinh C hay một ngôn ngữ công cụ UNIX nào khác. Khi đã quen thuộc với Perl, bạn. tính khả chuyển cao và lại có sẵn trên hầu hết các hệ thống. Giống như mọi ngôn ngữ khác, Perl có thể “chỉ viết” - tức là có thể viết ra chương trình cho

Ngày đăng: 22/10/2013, 11:15

Hình ảnh liên quan

Tuy nhiên, vào tên để cho ta có thể so sánh nó và tra cứu nó trong bảng thì sẽ &#34;phá huỷ&#34; mất tên ta vừa đưa vào - Ngôn ngữ Perl-Chương 01-Giới thiệu

uy.

nhiên, vào tên để cho ta có thể so sánh nó và tra cứu nó trong bảng thì sẽ &#34;phá huỷ&#34; mất tên ta vừa đưa vào Xem tại trang 11 của tài liệu.

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan