Biến đổi dữ liệu khác

19 324 0
Tài liệu đã được kiểm tra trùng lặp
Biến đổi dữ liệu khác

Đ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

Biến đổi dữ liệu khác Tìm một xâu con Tìm một xâu con phụ thuộc vào nơi bạn mất nó. Nếu bạn ngẫu nhiên mất nó bên trong một xâu lớn hơn, thì bạn còn may mắn, vì index() có thể giúp bạn tìm ra. Sau đây là dáng vẻ của nó: $x = index ($string, $substring) ; Perl định vị lần xuất hiện đầu tiên của substring bên trong string, cho lại một số nguyên chỉ vị trí của kí tự đầu tiên. Giá trị chỉ số này đợc cho lại dựa trên không - tức là nếu tìm đợc substring ở chỗ bắt đầu của string, thì bạn nhận đợc 0. Nếu nó là ở một kí tự sau đó thì bạn nhận đợc 1, và cứ nh thế. Nếu không tìm thấy substring trong string, thì bạn nhận đợc -1. Ta hãy xem những điều sau: $where = index(hello, e); # $where nhận 1 $oerson = barney; $where = index(fred barney, $person) ; # $where nhận 5 @rockers = (fred, barney) ; $where = index(join( , @rockers), $person); # cũng thế Chú ý rằng cả hai xâu này đều đợc tìm kiếm và xâu đợc tìm kiếm thì có thể là một hằng xâu kí hiệu, một biến vô hớng có chứa một xâu, hay thậm chí một biểu thức có giá trị xâu vô hớng. Sau đây là một số thí dụ nữa: $which = index(a very long string, long); # $switch nhận 7 $which = index(a very long string, lame); # $switch nhận -1 Nếu xâu có chứa xâu con tại nhiều vị trí thì toán tử index() sẽ cho lại vị trí bên trái nhất. Để tìm ra các vị trí sau, bạn có thể cho index() tham biến thứ ba. Tham biến này là giá trị tối thiểu mà index() sẽ cho lại, cho phép bạn tìm lần xuất hiện tiếp của xâu con theo sau một vị trí đã chọn. Nó trông tựa nh thế này: $x = index($bigtring, $littlestring, $skip); 1 Sau đây là một số thí dụ về cách tham biến thứ ba làm việc: $where = index(hello world, l); # cho lại 2 (l đầu tiên) $where = index(hello world, l, 0); # cũng thế $where = index(hello world, l, 1); # vẫn thế $where = index(hello world, l,3); # bây giờ cho lại 3 # (3 là vị trí đầu tiên lớn hơn hay bằng 3) $where = index(hello world, o, 5); # cho lại 7 (0 thứ hai) $where = index(hello world, o, 8); # cho lại -1 (hết sau 8) Đi theo lối khác, bạn có thể nhòm từ bên phải để có đợc sự xuất hiện bên phải nhất bằng việc dùng rindex(). Giá trị cho lại vẫn là số các kí tự giữa đầu bên trái của xâu và chỗ bắt đầu của xâu con, nh trớc, nhng bạn sẽ nhận đợc sự xuất hiện về bên phải nhất thay vì sự xuất hiện bên trái nhất nếu có nhiều sự xuất hiện. Toán tử rindex() cũng nhận tham biến thứ ba giống nh index() , để cho bạn có thể có đ- ợc sự xuất hiện ít hơn hay bằng vị trí đã chọn. Sau đây là một số thí dụ về điều bạn nhận đợc: $w = rindex(hello world, he); # $w nhận 0 $w = rindex(hello world, l); # $w nhận 9 (l bên phải nhất) $w = rindex(hello world, o); # $w nhận 7 $w = rindex(hello world, o ); # $w nhận 4 $w = rindex(hello world, xx); # $w nhận -1 (không thấy) $w = rindex(hello world, o, 6); # $w nhận 4 (đầu tiên trớc 6) $w = rindex(hello world,o, 3); # $w nhận -1 (không thấy trớc 3) Trích và thay thế một xâu con Việc lấy ra một mẩu của xâu có thể đợc thực hiện bằng việc áp dụng cẩn thận các biểu thức chính qui, nhng nếu mẩu này bao giờ cũng ở tại một vị trí kí tự đã biết, thì việc này là không hiệu quả. Thay vì vậy, bạn nên dùng substr(). Toán tử này nhận ba đối: một giá trị xâu, một vị trí bắt đầu (đợc đo tựa nh nó đã đợc đo cho index()), và một chiều dài, giống nh: $s = substr ($string, $start, $length); Vị trí bắt đầu làm việc giống nh index; kí tự đầu tiên là không, kí tự thứ hai là một, và cứ thế. Chiều dài là số các kí tự cần nắm lấy 2 tại điểm đó: chiều dài bằng không có nghĩa là không có kí tự nào, bằng một có nghĩa là lấy kí tự đầu tiên, bằng hai có nghĩa là hai kí tự, và vân vân. (Nó dừng lại tại cuối xâu, cho nên nếu bạn tìm kiếm quá nhiều, thì cũng không sao cả.) Nó trông giống thế này: $hello = hello, world!; $grab = substr($hello, 3, 2); # $grap nhận lo $grab = substr($hello, 7, 100); # 7 đến cuối, hay world! Bạn thậm chí có thể tạo ra toán tử nâng lên luỹ thừa mời cho các số mũ nguyên nhỏ, nh trong: $big = substr(10000000000, 0, $power+1); # 10**$power Nếu số đếm các kí tự là không hay bé hơn không, thì một xâu rỗng sẽ đợc cho lại. Mặt khác, nếu vị trí bắt đầu là bé hơn không thì vị trí bắt đầu đợc tính theo số các kí tự từ cuối xâu. Cho nên giá trị -1 đối với vị trí bắt đầu và 1 (hay nhiều) đối với chiều dài sẽ cho bạn kí tự cuối. Tơng tự, -2 cho vị trí bắt đầu với kí tự thứ hai kể từ cuối. Giống thế: $stuff = substr(a very long string, -3, 3); # ba kí tự cuối $stuff = substr(a very long string, -3, 1); # kí tự i Nếu vị trí bắt đầu là trớc chỗ mở đầu của xâu (giống nh một số âm khổng lồ lớn hơn chiều dài của xâu), thì chỗ mở đầu sẽ là vị trí bắt đầu (dờng nh bạn đã dùng 0 làm vị trí bắt đầu). Nếu vị trí bắt đầu là một số dơng khổng lồ, thì xâu rỗng bao giờ cũng đợc cho lại. Nói cách khác, nó có thể làm điều bạn trông đợi nó phải làm, chừng nào bạn còn trông đợi thì nó bao giờ cũng cho lại một cái gì đó khác hơn là một lỗi. Bỏ đi đối chiều dài thì cũng hệt nh bạn đã đa một số khổng lồ vào cho đối đó - nắm lấy mọi thứ từ vị trí đã chọn cho tới cuối xâu * . Nếu đối thứ nhất của substr() là một biến (nói cách khác, nó có thể xuất hiện bên vế trái của toán tử gán), thì bản thân substr() cũng có thể xuất hiện ở vế bên trái của toán tử gán. Điều này trông có vẻ kì lạ nếu bạn bắt nguồn từ nền tảng C, nhng nếu bạn đã chơi với vài dị bản của BASIC thì nó hoàn toàn là thông thờng. Điều nhận đợc sự thay đổi nh kết quả của phép gán nh thế là phần của xâu sẽ đợc cho lại, mà có substr() đợc dùng trong một biểu thức. Nói cách khác, substr($var, 3, 2) cho lại kí tự thứ t và thứ năm (bắt đầu từ 3, vì số đếm 2), cho nên việc gán điều đó làm thay đổi hai kí tự này cho $var. Giống nh: * * Các bản Perl cổ hơn không cho phép bỏ đi đối thứ ba, dẫn tới việc những lập trình viên Perl tiền phong đã dùng số khổng lồ cho đối đó. Bạn có thể vợt qua điều này trong cuộc hành trình khảo cổ Perl của mình. 3 $hw = hello world!; substr($hw, 0, 5) = howdy; # $hw bây giờ là howdy world! Chiều dài của văn bản thay thế (cái nhận đợc việc gán vào trong substr) không phải là cùng nh văn bản đợc thay thế, nh trong thí dụ này. Xâu này sẽ tự động tăng trởng hay co lại khi cần để điều hào với văn bản. Sau đây là một thí dụ về việc xâu thành ngắn hơn: substr($hw, 0, 5) = hi; # $hw bây giờ là hi world! và đây là một xâu thành dài hơn: substr($hw, -6, 5) = worldwide news; # thay thế world Việc co lại hay dãn ra thì khá hiệu quả, cho nene bạ nđừng lo lắng về việc dùng chúng một cách bất kì, mặc dầu việc thay thế một xâu bằng một xâu chiều dài tơng đơng thì vẫn nhanh hơn nếu bạn có cơ hội. Định dạng dữ liệu bằng sprintf() Toán tử printf đôi khi cũng dễ sử dụng khi đợc dùng để lấy một danh sách các giá trị và tạo ra một dòng ra cho hiển thị các giá trị đó theo cách điều khiển đợc. Toán tử sprintf() là đồng nhất với printf về các đối, nhng cho lại bất kì cái gì đã đợc printf đa ra nh một xâu riêng biệt. (hãy nghĩ về điều này nh xâu printf.) Chẳng hạn, để tạo ra một xâu bao gồm chữ X theo sau bởi một giá trị năm chữ số lấp đầy bởi không của $y, cũng dễ dàng nh: $result = sprintf(X%05d, $y); Nếu bạn không quen thuộc với xâu định dạng của printf và sprintf, thì hãy tham khảo vào tài liệu printf hay sprintf. (Tên sprintf, trong thực tế có nguồn gốc từ trình th viện cùng tên.) Sắp xếp nâng cao Trớc đây, bạn đã biết rằng bạn có thể lấy một danh sách rồi sắp xếp nó theo thứ tự ASCII tăng dần (nh các xâu), bằng cách dùng toán tử sort có sẵn. Điều gì sẽ xẩy ra nếu bạn không muốn sắp xếp theo thứ tự ASCII tăng dần, mà thay vì thế là một cái gì đó khác, kiểu nh sắp xếp số? Đợc, Perl cho bạn công cụ bạn cần để làm việc này. Trong thực tế, bạn sẽ thấy rằng sort của Perl là hoàn toàn tổng quát và có thể thực hiện bất kì thứ tự sắp xếp nào. Để định nghĩa việc sắp xếp theo mầu sắc khác, bạn cần định nghĩa một trình so sánh mà mô tả cho cách so sánh hai phần tử. Tại sao 4 điều này lại cần thiết? Đợc, nếu bạn nghĩ về nó, thì sắp xếp là việc đặt một bó các thứ theo một trật tự so sánh tất cả chúng với nhau. Vì bạn không thể nào so sánh chúng ngay một lúc nên bạn cần so sánh hai phần tử mỗi lúc, để cuối cùng dùng cái bạn phát hiện ra về thứ tự cho từng cặp mà đặt toàn bộ cả lũ vào hàng. Trình so sánh đợc định nghĩa nh một trình thông thờng. Trình này sẽ đợc gọi đi gọi lại, mỗi lần lại truyền hai phần tử của danh sách cần đợc sắp. Trình này phải xác định liệu giá trị thứ nhất là bé hơn, bằng hay lớn hơn giá trị thứ hai, và cho lại một giá trị mã hoá (sẽ đ- ợc mô tả ngay sau đây). Tiến trình này đợc lặp lại cho tới khi danh sách đợc sắp hoàn toàn. Để tiết kiệm tốc độ thực hiện một chút, hai giá trị này không đợc truyền trong ảng, mà thay vì thế đợc trao cho một trình con nh giá trị của biến toàn cục $a và $b. (Bạn đừng lo - giá trị nguyên thuỷ của $a và $b đợc bảo vệ an toàn.) Trình này nên cho lại một giá trị âm nào đó nếu $a bé hơn $b, bằng không nếu $a bằng $b, và bất kì số dơng nào nếu $a lớn hơn $b. Bây giờ bạn hãy nhớ, bé hơn là tơng ứng với ý nghĩa của bạn về bé hơn - nó có thể là một so sánh số, tơng ứng với kí tự thứ ba của xâu, hay thậm chí tơng ứng với giá trị của bất kì mảng nào có dùng các giá trị đợc truyền vào nh khoá. Đấy mới thực sự là mềm dẻo. Sau đây là một thí dụ về một chơng trình con sắp xếp mà sẽ sắp mọi thứ theo thứ tự số: sub by_number { if ($a < $b) { -1; } elsif ($a == $b) { 0; } elsif ($a > $b) { 1; } } Bạn hãy chú ý đến tên by_number. Không có gì đặc biệt về cái tên của trình con này, nhng bạn sẽ thấy tại sao tôi lại thích cái tên bắt đầu bởi by_ trong giây lát. Ta hãy nhìn qua trình con này. Nếu giá trị của $a là bé hơn (về mặt số trong trờng hợp này) giá trị của $b, thf ta cho lại giá trị -1. Nếu các giá trị là bằng nhau về con số thì ta cho lại không, còn ngoài ra cho lại 1. Vậy, theo mô tả của ta cho trình so sánh sắp xếp thì điều này sẽ làm việc. 5 Làm sao ta dùng đợc nó? Ta hãy thử sắp xếp danh sách sau. $somelist = (1,2,4,8,16,32,64,128,256); Nếu ta dùng sort thông thờng không sang sửa lại danh sách thì ta sẽ đợc các số sắp nh chúng là các xâu, và theo trật tự ASCII, tựa nh: @wronglist = sort @somelist; # @wronglist bây giờ là (1,128,16,2,256,32,64,8) Chắc chắn đấy không phải là sắp xếp số. Thôi đợc, ta sẽ cho sort một trình sắp xếp đợc định nghĩa mới. Tên của trình sắp xếp đi ngay sau từ khoá sort, nh: @rightlist = sort by_number @wronglist; # @rightlist bây giờ là (1,2,4,8,32,64,128,256) Đây quả là mẹo. Chú ý rằng bạn có thể đọc sort với trình con sắp xếp đi kèm theo kiểu con ngời: sắp xếp theo số. Đó là lí do tại sao tôi đặt tên cho trình con với tiền tố by_. Nếu bạn cũng thiên về nh thế và muốn nhấn mạnh rằng cái đi sau sort là một trình con, thì bạn có thể đặt trớc nó bằng một dấu và (&), khi đó Perl sẽ không bận tâm nữa, nhng nó đã biết rằng cái nằm giữa từ khoá sort và danh sách phải là một tên trình con. Cái loại giá trị ba ngả kiểu -1, 0, 1 dựa trên cơ sở so sánh số thờng xuất hiện trong trình con so sánh đến mức Perl có một toán tử đặc biệt để làm điều này trong một lần. nó thờng đợc gọi là toán tử tầu vũ trụ, và trông giống <=>. Dùng toán tử tầu vũ trụ này, trình con sắp xếp trên đây có thể đợc thay thế bằng: sub by_number { $a <=> $b; } Bạn hãy chú ý đến con tầu vũ trụ giữa hai biến này. Quả vậy, nó thực là toán tử dài ba kí tự. Con tầu vũ trụ cho lại cùng giá trị nh dây chuyền if/elsif trong định nghĩa trớc của trình này. Bây giờ điều này là có ngắn gọn, nhng bạn có thể viết tắt lời gọi sắp xếp thêm nữa, bằng việc thay thế tên của trình sắp xếp bằng toàn bộ trình sắp xếp trong dòng, giống nh: @rightlist = sort { $a <=> $b } @wronglist; 6 Một số ngời biện minh rằng điều này làm giảm tính dễ đọc. Một số khác thì lại biện minh rằng nó loại bỏ nhu cầu phải đi đâu đó để tìm ra định nghĩa. Perl chẳng quan tâm đến điều đó. Qui tắc cá nhân của tôi là ở chỗ nếu nó không khớp trên một dòng hay tôi phải dùng nó nhiều lần, thì nó nên thành một trình con. Toán tử tầu vũ trụ dành cho so sánh số, có toán tử xâu so sánh gọi là cmp. Toán tử cmp cho lại một trong ba giá trị tuỳ theo việc so sánh xâu tơng đối của hai đối. Cho nên, một cách khác để viết trật tự mặc định là: @result = sort { $a cmp $b } @somelist; Có lẽ bạn còn cha hề viết trình con đích xác này (bắt chớc sắp xếp mặc định có sẵn), chừng nào bạn còn cha viết một cuốn sách về Perl. Tuy thế, toán tử cmp vẫn có ích lợi của nó, trong việc xây dựng các lợc đồ sắp thứ tự theo tầng. Chẳng hạn, bạn không cần đặt các phần tử theo thứ tự số chừng nào chúng không bằng nhau về mặt số, và trong trờng hợp đó chúng phải đợc sắp theo trật tự ASCII. (Theo ngầm định, trình by_number trên sẽ chỉ dùng cho các xâu phi số theo một trật tự ngẫu nhiên nào đó vì không có trật tự số khi so sánh hai giá trị không.) Sau đây là một cách nói cần so sánh theo số, chừng nào chúng cha bằng nhau về số, còn thì so sánh theo xâu: sub by_mostly_number { ($a <=> $b) || ($a cmp $b); } Điều này làm việc thế nào? Thế này, nếu kết quả của tầu vũ trụ là -1 hay 1 thì phần còn lại của biểu thức bị bỏ qua, và giá trị -1 hay 1 đợc cho lại. Néu tầu vũ trụ tính ra giá trị không thì toán tử cmp trở thành quan trọng, cho lại một giá trị thứ tự thích hợp xem nh giá trị của xâu. Giá trị đợc so sánh không nhất thiết là giá trị đợc truyền vào. Chẳng hạn, bạn có một mảng kết hợp trong đó khoá là tên đăng nhập và các giá trị là tên thật của từng ngời dùng. Giả sử bạn muốn in ra một biểu đồ trong đó tên đăng nhập và tên thật đợc cất giữ theo thứ tự tên thật. Bạn sẽ làm điều đó nh thế nào? Thực tại, việc ấy khá dễ dàng. Ta hãy giả sử các giá trị là trong mảng %names. Tên đăng nhập vậy là danh sách của key(%names). Điều ta muốn đạt tới là một danh sách các tên đăng nhập đợc sắp theo giá trị tơng ứng, vậy với bất kì khoá riêng $a nào, ta cần nhìn vào $names{$a} và sắp xếp dựa trên điều đó. Nếu bạn nghĩ về điều này theo cách đó thì nó gần nhu đã tự viết ra rồi, nh trong: @sortedkeys = sort by_names keys(%names); sub by_names { 7 $names{$a} cmp $names{$b}; } foreach (@sortedkeys) { print $_ có tên thật là $names{$_}\n; } Với điều này tôi cũng đã thêm vào một so sánh. Giả sử tên thật của hai ngời dùng là trùng nhau. Vì bản chất chợt nẩy ra của trình sort, tôi có thể lấy một giá trị này trớc giá trị kia lần đầu tiên rồi các giá trị theo thứ tự đảo lại cho lần sau. Điều này không tốt nếu báo cáo có thể đợc nạp vào chơng trình so sánh cho việc báo cáo, cho nên tôi phải rất cố gắng tránh những thứ nh vậy. Với toán tử cmp, thật dễ dàng: sub by_names { ($names{$a} cmp $names{$b}) || ($a cmp $b); } Tại đây, nếu tên thực là giống nhau thì tôi sắp xếp dựa trên tên đăng nhập. Vì tên đăng nhập đợc đảm bảo là duy nhất (sau rốt, chúng là các khoá của mảng kết hợp này, và không có hai khoá nào là nh nhau), nên tôi có thể đảm bảo một trật tự duy nhất và lặp lại đ- ợc. Việc lập trình phòng ngự tốt trong những ngày này thì tốt hơn là một cú điện thoại gọi đêm của thao tác viên để hỏi làm sao tắt đi còi báo động. Chuyển tự Khi bạn muốn lấy một xâu và thay thế mọi thể nghiệm của một kí tự nào đó bằng một kí tự mới, hay xoá mọi thể nghiệm của một kí tự nào đó, thì bạn có thể đã làm điều đó với việc chọn lựa cẩn thận chỉ lệnh s///. Nhng giả sử bạn phải thay đổi tất cả các a thành b và tất cả các b thành a thì sao? Bạn không thể làm điều đó với hai chỉ lệnh s/// vì chỉ lệnh thứ hai sẽ hoàn tác lại tất cả những thay đổi do chỉ lệnh thứ nhất thực hiện. Tuy nhiên từ vỏ, một phép chuyển đổi dữ liệu nh vậy là đơn giản - chỉ cần dùng chỉ lệnh tr chuẩn: tr ab ba < indata >outdata (Nếu bạn không biết gì về chỉ lệnh tr, xin xem tài liệu - đó là một công cụ có ích cho túi các mẹo của bạn.) Tơng tự, Perl cung cấp một toán tử tr làm việc rất giống nh thế: 8 tr/ab/ba/; Toán tử tr nhận hai đối : xâu cũ và xâu mới. Các đối này làm việc giống nh hai đối của s///: nói cách khác, có một định bên nào đó xuất hiện ngay sau từ khoá tr làm tách biệt và kết thúc hai đối (trong trờng hợp này, một sổ chéo, nhng gần nh kí tự nào cũng đợc). Các đối cho toán tử tr giống hệt nh các đối của chỉ lệnh tr. Toán tử tr sửa đổi nội dung của biến $_ (giống nh s///), tìm các kí tự của xâu cũ bên trong biến $_. Tất cả các kí tự nh thế đợc tìm thấy đều đợc thay thế bằng kí tự tơng ứng trong xâu mới. Sau đây là một số thí dụ: $_ = fred and barney; tr/fb/bf/; # $_ bây giờ là bred and farney tr/abcde/ABCDE/; # $_ bây giờ là BrED AnD fArnEy tr/a-z/A-Z/; # $_ bây giờ là BRED AND FARNEY Bạn hãy lu ý đến phạm vi các kí tự có thể đợc chỉ ra bằng hai kí tự đợc phân cách bởi sổ chéo. Nếu bạn cần một sổ chéo hằng kí tự trong xâu thì hãy đặt trớc nó một sổ chéo ngợc. Nếu xâu mới ngắn hơn xâu cũ, thì kí tự cuối cùng của xâu mới sẽ đợc lặp lại đủ số lần để làm cho các xâu có chiều dài nh nhau, giống nh: $_ = fred and barney; tr/a-z/ABCDE/d; # $_ bây giờ là ED AD BAE Bạn hãy lu ý đến cách thức mọi chữ sau e đều biến mất vì không có kí tự tơng ứng trong danh sách mới và rằng các dấu cách không bị tác động vì chúng không xuất hiện trong danh sách cũ. Điều này là tơng tự với thao tác của tuỳ chọn -d của chỉ lệnh tr. Nếu danh sách mới là rỗng và nếu không có tuỳ chọn d thì danh sách mới là giống hệt danh sách cũ. Điều này có vẻ hơi ngu, vì tại sao phảti thay thế I cho I và 2 cho 2, nhng thực tế thì nó cũng làm đôi điều ích lợi đấy. Giá trị cho lại của toán tử tr/// là số các kí tự đợc sánh theo xâu cũ, và bằng việc thay đổi các kí tự trong chính chúng, bạn có thể nhận đợc số các loại kí tự đó bên trong xâu. Chẳng hạn: $_ = fred and barney; $count = tr/a-z//; # $_ không thay đổi nhng $count là 13 $count2 = tr/a-z/A-Z/; # $_ là chữ hoa còn $count2 là 13 Nếu bạn thêm c vào cuối (giống nh viết thêm d) thì điều đó có nghĩa là làm đầy đủ xâu cũ đối với tất cả 256 kí tự. Bất kì kí tự nào 9 bạn liệt kê trong xâu cũ đều bị loại bỏ khỏi tập tất cả các kí tự có thể; các kí tự còn lại, đợc lấy theo dẫy từ thấp đến cao, từ xâu cũ. Vậy, một cách để đếm hay thay đổi các kí tự phi số trong xâu của chúng ta có thể là: $_ = fred and barney; $count = tr/a-z//c; # $_ không đổi, nhng $count là 2 tr/a-z/_/c; # $_ bây giờ là fred_and_barney (phi chữ => _) tr/a-z//cd; # $_ bây giờ là fredandbarney (xoá kí tự khác chữ) Chú ý rằng các tuỳ chọn có thể đợc tổ hợp, nh đợc trình bầy trong thí dụ cuối, nơi chúng ta trớc hết bổ dung cho tập hợp (danh sách các chữ trở thành danh sách của tất cả các phi chữ) rồi dùng tuỳ chọn d để xoá bất kì kí tự nào trong tập đó. Tuỳ chọn cuối cùng cho tr/// là s, mà sẽ làm cứng lại nhiều bản sao liên tiếp của cùng chữ đã đợc dịch vào một bản sao. Zem nh một thí dụ ta hãy nhìn vào điều này: $_ = aaabbcccdefghi; tr/defghi/abcdd/s; # $_ bây giờ là aaabbcccabcd Chú ý rằng def trở thành abc, còn ghi (mà đáng trở thành ddd nếu không có tuỳ chọn s) lại trở thành một d. Bạn cũng để ý rằng các chữ liên tiếp tại phần đầu của xâu thì không bị đóng cứng lại vì chúng không là kết quả của việc dịch. Sau đây là thêm một số thí dụ nữa: $_ = fred and barney, wilma and betty; tr/a-z/X/s; # $_ bây giờ là X X X, X X X $_ = fred and barney, wilma and betty; tr/a-z/_/cs; # $_ bây giờ là fred_and_barney_wilma_and_betty Trong thí dụ thứ nhất, mỗi từ (chữ liên tiếp) đều bị đóng cứng lại chỉ một chữ X. Trong thí dụ thứ hai, tất cả chùm các phi chữ liên tiếp trở thành dấu gạch thấp duy nhất. Giống nh s///, toán tử tr có thể hớng đích vào một xâu khác bên cạnh $_ bằng việc dùng toán tử =~: $name = fred and barney; $name =~ tr/aeiou/X/; # $name bây giờ là frXd Xnd bXrnXy 10 [...]... coi việc này nh bớc sao chép - dữ liệu đợc sao từ cơ sở dữ liệu nguyên gốc sang một bản mới của cơ sở dữ liệu ấy, tiến hành tahy đổi trong khi sao chép Perl hỗ trợ cho việc soạn thảo kiểu sao chép này trên các cơ sở dữ liệu hớng dòng bằng cách dùng việc soạn thảo tại chỗ Soạn thảo tại chỗ là việc sửa đổi cách thức toán tử hình thoi () đọc dữ liệu từ một danh sách các tệp đợc xác định trong dòng lệnh... Mảng kết hợp này (còn gọi là mảng DBM) vậy rồi đợc dùng để thâm nhập và sửa đổi cơ sở dữ liệu DBM Việc tạo ra một phần tử mới trong mảng này làm thay đổi ngay lập tức cơ sở dữ liệu DBM Việc xoá một phần tử sẽ xoá giá trị khỏi cơ sở dữ liệu DBM Và cứ nh thế Kích cỡ, số lợng và loại khoá cùng giá trị trong cơ sở dữ liệu DBM thì có hạn chế, và một mảng DBM có cùng những hạn chế đó Bạn hãy xem lidbm về... Th của Randal đợc gắn đầu cho: $value\n; # in kết quả Bản UNIX của bạn có thể đa cơ sở dữ liệu biệt hiệu vào /usr/lib thay vì /etc Bạn phải lục lọi để tìm ra Cơ sở dữ liệu thâm nhập ngẫu nhiên chiều dài cố định Một dạng khác của dữ liệu bền bỉ là các tệp đĩa hớng bản ghi với chiều dài cố định Trong lợc đồ này, dữ liệu bao gồm một số các bản ghi với chiều dài nhu nhau Việc đánh số cho các bản ghi thì... tất cả dữ liệu từ vị trí hiện tại cho tới dòng 16 mới tiếp, điều đó lại không đúng; dữ liệu đợc giả thiết là chỉ trải trên 83 kí tự và có thể lại không có dòng mới ở đúng chỗ Thay vì thế, ta dùng toán tử read(), trông và cách làm việc thì hệt nh lời gọi hệ thống UNIX tơng ứng: $count = read(NAMES, $buf, 83); Tham biến thứ nhất của read() là tức hiệu tệp Tham biến thứ hai là biến vô hớng mà giữ dữ liệu. .. sở dữ liệu này đợc cập nhật bằng các trình soan thảo văn bản đơn giản Việc cập nhật một cơ sở dữ liệu nh vậy bao gồm việc đọc nó tất cả vào một vùng trung gian (hoặc trong bộ nhớ hoặc trên đĩa khác) , thực hiện những thay đổi cần thiết, rồi hoặc ghi kết quả ngợc trở lại tệp nguyên thuỷ hoặc tạo ra một tệp mới với cùng tên sau khi đã xoá hay đổi tên bản cũ Bạn có thể coi việc này nh bớc sao chép - dữ liệu. .. của câu thành chữ thờng (Liệu nó có làm việc cả khi kí tự đầu tiên không phải là một chữ không? Bạn làm điều này thế nào nếu câu không trên một dòng?) 11 16 Thâm nhập cơ sở dữ liệu hệ thống 12 17 Thao tác cơ sở dữ liệu ngời dùng Cơ sở dữ liệu DBM và mảng DBM Phần lớn các hệ thống UNIX đều có một th viện chuẩn gọi là DBM Th viện này cung cấp một tiện nghi quản trị cơ sở dữ liệu đơn giản mà cho phép... vào cơ sở dữ liệu DBM hệ thống, nh các cơ sở dữ liệu đã đợc tạo ra bởi sendmail hay tin Usenet, thì bạn phải biết rằng các chơng trình nói chung đều gắn thêm cái đuôi kí tự NUL (\0) vào cuối của các xâu này Các trình th viện DBM không cần cái NUL này (chúng giải quyết dữ liệu nhị phân bằng cách đếm byte chứ không phải là xâu kết thúc bằng NUL), và do vậy NUL đợc cất giữ nh một phần của dữ liệu Do đó... lớn các chơng trìnhcất giữ xâu này trong một biến từ đầu trong chơng trình, và thậm chí còn tính chiều dài của bản ghi bằng việc dùng pack() thay vì bỏ rải rác các hằng 83 ở mọi nơi: $names = A40AA40s; $names_length = length(pack($names)) ; # có thể là 83 Cơ sở dữ liệu (văn bản) chiều dài thay đổi Nhiều cơ sở dữ liệu hệ thống (và có lẽ phần lớn cơ sở dữ liệu do ngời dùng tạo ra) đều là các chuỗi dòng... sở dữ liệu DBM Phần mềm tin Usenet phủ cập nhất cũng dùng cơ sở dữ liệu DBM để giữ dấu vết cac bài báo hiện tại và mới xem gần đấy Perl cung cấp việc thâm nhập vào cùng cơ chế DBM này thông qua một phơng tiện còn thông minh hơn: mảng kết hợp có thể đợc kết hợp với cơ sở dữ liệu DBM qua một tiến trình tơng tự nh mở một tập Mảng kết hợp này (còn gọi là mảng DBM) vậy rồi đợc dùng để thâm nhập và sửa đổi. .. cơ sở dữ liệu giữa những lần gọi chơng trình có dùng cơ sở dữ liệu và những chơng trình này có thể bổ sung các giá trị mới, cập nhật các giá trị hiện có, hay xoá các giá trị cũ Th viện DBM thì khá đơn giản, nhng lại sẵn có, một số chơng trình hệ thống đã dùng nó cho những nhu cầu khá giản dị của chúng Chẳng hạn, chơng trình gửi th Berkeley (và các biến thể cùng suy dẫn của nó) cất giữ cơ sở dữ liệu . sở dữ liệu biệt hiệu vào /usr/lib thay vì /etc. Bạn phải lục lọi để tìm ra. Cơ sở dữ liệu thâm nhập ngẫu nhiên chiều dài cố định Một dạng khác của dữ liệu. length(pack($names)) ; # có thể là 83 Cơ sở dữ liệu (văn bản) chiều dài thay đổi Nhiều cơ sở dữ liệu hệ thống (và có lẽ phần lớn cơ sở dữ liệu do ngời dùng tạo ra) đều

Ngày đăng: 28/09/2013, 10:20

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

Tài liệu liên quan