1 / 3
Caption Text
2 / 3
Caption Two
3 / 3
Caption Three margin testing

Showing posts with label Perl. Show all posts
Showing posts with label Perl. Show all posts

Monday, July 27, 2009

Perl中三個使用=~ 符號的運算子

http://www.cyut.edu.tw/~ckhung/b/pl/idiom.ph

三個使用 =~ 符號的運算子

  1. $var =~ tr/.../.../; 把變數 $var 內的 ... 字元都逐一代換成 ... 字元 兩串 ... 通常長度一樣. 想成是查 "字元典" 翻譯。 (較不常用)
  2. $var =~ s/.../.../; 把變數 $var 內的第一個 ... 子字串整個代換成 ... 子字串。
  3. if ($var =~ m/.../) { ... } 詢問變數 $var 裡面有沒有 ... 這個子字串呢?

注意:

  1. 前兩項功能是破壞性的 (destructive), $var 的內容可能因而改變; 第三項是非破壞性的 (non-destructive)。
  2. 後兩項功能在現實生活中較常用到; 兩者都支援 regular expression
  3. 其實可以用其他標點符號來取代斜線, 只要一句話內前後一致就好。
  4. 其實第三項功能的 m 可以省略掉
  5. 如果 $var 是 $_ 則可以用簡寫, 把 $var =~ 全部省略掉。

代換字串 ... =~ s/.../.../ 時, 可以加上一些選項, 例如

i (ignore) 表示忽略大小寫 (比對成功的條件變得更寬鬆);
g (global) 表示全面代換, 不只代換第一個比對成功的子字串。

神奇的內定參數 $_

在很多場合下, 參數可以省略不寫, 而此時 perl 自動以 $_ 作為內定參數. 例如:

  1. 用 <FH> 從檔案讀入的一列, 自動存在 $_ 中.
  2. 許多運算子的參數, 例如 tr, s, m.
  3. 許多函數的參數, 例如 print, chomp, split, ...
  4. foreach 的 dummy variable.



Sunday, July 26, 2009

处理 UTF-8 编码文件时输出和写入乱码问题

解决处理 UTF-8 编码XML文件时,输出和写入乱码问题

以前用 Perl 处理 UTF-8 编码的 XML 文件时,总是遇到奇怪的问题:

单独输出读取的中文 XML 信息,没有问题,但是一旦和其他中文字符(比如定义的中文变量)混合输出就会出现乱码

eg:
$xml->{"chunk"}{"comment"} 包含了中文信息
my $cnstr="变量中的中文信息";

## 出现乱码
print $xml->{"chunk"}{"comment"} . $cnstr ;

## 正常
print $xml->{"chunk"}{"comment"};
print $cnstr;


仔细研究了下 UTF8 下中文处理 [转载]Perl中的unicode问题及解决办法(译),现在总算找到原因了:

UTF-8 编码的 XML 文件默认就含有 utf8 标记,而一般自定义的变量不含,两者混合输出时,Perl 会认为两者都不含或都含(看谁在前) utf8 标记,于是乱码就产生了。

解决办法:
读取 XML 文件后,用 Encode::_utf8_off($str) 来去掉 utf8 标记
写入 XML 文件前,用 Encode::_uft8_on($str) 加上 utf8 标记

如:
### 读取
$comment = $xml->{"chunk"}{"comment"};
Encode::_utf8_off($comment);
...

### 写入
$comment= param('comment'); ## 获取网页提交的信息
Encode::_utf8_on($comment);
$xml->{"chunk"}{"comment"} = $comment;
....

Perl笔记: UTF8下中文处理

Perl笔记: UTF8下中文处理

发信人: happierbee (吾生也有涯,而知也无涯), 信区: Perl
标 题: UTF8下中文处理
发信站: 水木社区 (Mon Sep 11 21:22:53 2006), 站内

我来总结一下吧。先建一个文件test.txt, 写上 中文 两个字。运行下面一个程序:

use strict;
use warnings;
use Encode;
my $str_code = "中文";
my $file = "test.txt";

open(my $fh, $file) || die "Can't open file $file: $!";
chomp(my $str_file = <$fh>);
close $fh;

open(my $fh_utf8, "<:utf8", $file) || die "Can't open file $file: $!";
chomp(my $str_fileu = <$fh_utf8>);
close $fh_utf8;

test_utf8($str_code, "code");
test_utf8($str_file, "file");
test_utf8($str_fileu, "file(utf8 layer)");
# print $str_code, "\n";
# print $str_file, "\n";
# print $str_fileu, "\n";

Encode::_utf8_on($str_code);
Encode::_utf8_on($str_file);
test_utf8($str_code, "code");
test_utf8($str_file, "file");

sub test_utf8 {
my ($str, $type) = @_;
if ( Encode::is_utf8($str) ) {
print "String from $type, utf8 flag is on."
} else {
print "String from $type, utf8 flag is off."
}
my @chars = split('', $str);
# print join("\t", @chars), "length: ", scalar(@chars);
if (scalar(@chars)==2) {
print " Can match chinese character.";
} else {
print " Can't match chinese character.";
}
print "\n";
}

结果如下:
String from code, utf8 flag is off. Can't match chinese character.
String from file, utf8 flag is off. Can't match chinese character.
String from file(utf8 layer), utf8 flag is on. Can match chinese character.
Turn on utf flag:
String from code, utf8 flag is on. Can match chinese character.
String from file, utf8 flag is on. Can match chinese character.

所以如果要想使用汉字作为一个字符的特性,就要在 open 里指明 io layer 为
utf8,同样,输出指明 utf8,然后在脚本里写 use utf8。
这样你就不用担心 utf8 下的乱码,又能享受汉字做为一个字符来写正则表达式的
的畅快。

如果不知道我上面说的意思,我就给一个例子:

use strict;
use warnings;
use Encode;
use utf8;

my $file = "test.txt";
my $outfile = "test-out.txt";

# open(my $fh, $file) || die "Can't open file $file: $!";
# open(my $out, '>:utf8', $outfile) || die "Can't open file $outfile: $!";

# select $out;

open(my $fh, '<:utf8', $file) || die "Can't open file $file: $!";

binmode STDOUT, ":utf8";

while (<$fh>) {

if (/[汉]/) {
unless (Encode::is_utf8($_)) {

Encode::_utf8_on($_);
}
print $_;

}

}

test.txt 中的内容是:"求\n汉\n汁\n汗\n汕\n江\n"(每个汉字一行的意思)。
这个例子中,有好几个组合:
1. 不使用 utf8 指令,open 中也不使用 utf8。
这时所有行都匹配。因为正则表达式中是三个字节(我假定你也用 utf8 来编码
代码,如果不是,可以不匹配任何行),而所有输入的行中都含有这三个字节中
的一个,事实上 test.txt 是我精心挑选的,前两个字节都相同的汉字。
2. 不使用 utf8 指令, open 中使用 utf8.
不能匹配任何行。因为输入文件中是汉字,而正则表达式是三个字节。
3. 使用 utf8 指令,open 中不使用 utf8
也不能匹配任何行。因为正则表达式中是一个汉字,而输入文件是一个个的字节。
4. 使用 utf8 指令,open 中也使用 utf8
正确匹配一行。

至于输出的 warning,这确实这是一个小小的 warning,不会影响结果。如果不
想有这个 warning,最好的办法是用 binmode 或者在 open 中指定使用 utf8
layer。或者对于 warning 的字符串用 Encode 模块中 _utf8_on 函数,强制
加上 utf8 flag.

perl 中文处理技巧

perl 中文处理技巧

Perl从5.6开始已经开始在内部使用utf8编码来表示字符,也就是说对中文以及其他语言字符的处理应该是完全没有问题的。我们只需要利用好Encode这个模块便能充分发挥Perl的utf8字符的优势了。

下面就以中文文本的处理为例进行说明,比如有一个字符串"测试文本",我们想要把这个中文字符串拆成单个字符,可以这样写:

use Encode;
$dat="测试文本";
$str=decode("gb2312",$dat);
@chars=split //,$str;
foreach $char (@chars) {
print encode("gb2312",$char),"\n";
}

结果大家试一试就知道了,应该是令人满意的。

这里主要用到了Encode模块的decode、encode函数。要了解这两个函数的作用我们需要清楚几个概念:
  1. Perl字符串是使用utf8编码的,它由Unicode字符组成而不是单个字节,每个utf8编码的Unicode字符占1~4个字节(变长)。
  2. 进入或离开Perl处理环境(比如输出到屏幕、读入和保存文件等等)时不是直接使用Perl字符串,而需要把Perl字符串转换成字节流,转换过程中使用何种编码方式完全取决于你(或者由Perl代劳)。一旦Perl字符串向字节流的编码完成,字符的概念就不存在了,变成了纯粹的字节组合,如何解释这些组合则是你自己的工作。

我们可以看出如果想要Perl按照我们的字符概念来对待文本,文本数据就需要一直用Perl字符串的形式存放。但是我们平时写出的每个字符一般都被作为纯ASCII字符保存(包括在程序中明文写出的字符串),也就是字节流的形式,这里就需要encode和decode函数的帮助了。

encode函数顾名思义是用来编码Perl字符串的。它将Perl字符串中的字符用指定的编码格式编码,最终转化为字节流的形式,因此和Perl处理环境之外的事物打交道经常需要它。其格式很简单:
$octets = encode(ENCODING, $string [, CHECK])
$string:  Perl字符串
encoding: 是给定的编码方式
$octets:  是编码之后的字节流
check:   表示转换时如何处理畸变字符(也就是Perl认不出来的字符)。一般不需使用
编码方式视语言环境的不同有很大变化,默认可以识别utf8、ascii、ascii-ctrl、 iso-8859-1等。

decode函数则是用来解码字节流的。它按照你给出的编码格式解释给定的字节流,将其转化为使用utf8编码的Perl字符串,一般来说从终端或者文件取得的文本数据都应该用decode转换为Perl字符串的形式。它的格式为:
$string = decode(ENCODING, $octets [, CHECK])
$string、ENCODING、$octets和CHECK的含义同上。

现在就很容易理解上面写的那段程序了。因为字符串是用明文写出的,存放的时候已经是字节流形式,丧失了本来的意义,所以首先就要用 decode函数将其转换为Perl字符串,由于汉字一般都用gb2312格式编码,这里decode也要使用gb2312编码格式。转换完成后Perl 对待字符的行为就和我们一样了,平时对字符串进行操作的函数基本上都能正确对字符进行处理,除了那些本来就把字符串当成一堆字节的函数(如vec、 pack、unpack等)。于是split就能把字符串切成单个字符了。最后由于在输出的时候不能直接使用utf8编码的字符串,还需要将切割后的字符用encode函数编码为gb2312格式的字节流,再用print输出。

Friday, July 24, 2009

Perl String Functions

String Functions

Perl provides a very useful set of string handling functions:

The first set of functions that we'll look at are those that deal with strings. These functions let you determine a string's length, search for a sub-string, and change the case of the characters in the string, among other things.

Here are Perl's string functions:

  • chomp(STRING) OR chomp(ARRAY) -- Uses the value of the $/ special variable to remove endings from STRING or each element of ARRAY. The line ending is only removed if it matches the current value of $/.
  • chop(STRING) OR chop(ARRAY)-- Removes the last character from a string or the last character from every element in an array. The last character chopped is returned.
  • chr(NUMBER) -- Returns the character represented by NUMBER in the ASCII table. For instance, chr(65) returns the letter A.
  • crypt(STRING1, STRING2) -- Encrypts STRING1. Unfortunately, Perl does not provide a decrypt function.
  • index(STRING, SUBSTRING, POSITION) -- Returns the position of the first occurrence of SUBSTRING in STRING at or after POSITION. If you don't specify POSITION, the search starts at the beginning of STRING.
  • join(STRING, ARRAY) -- Returns a string that consists of all of the elements of ARRAY joined together by STRING. For instance, join(">>", ("AA", "BB", "cc")) returns "AA>>BB>>cc".
  • lc(STRING) -- Returns a string with every letter of STRING in lowercase. For instance, lc("ABCD") returns "abcd".
  • lcfirst(STRING) -- Returns a string with the first letter of STRING in lowercase. For instance, lcfirst("ABCD") returns "aBCD".
  • length(STRING) -- Returns the length of STRING.
  • rindex(STRING, SUBSTRING, POSITION) -- Returns the position of the last occurrence of SUBSTRING in STRING at or after POSITION. If you don't specify POSITION, the search starts at the end of STRING.
  • split(PATTERN, STRING, LIMIT) -- Breaks up a string based on some delimiter. In an array context, it returns a list of the things that were found. In a scalar context, it returns the number of things found.
  • substr(STRING, OFFSET, LENGTH) -- Returns a portion of STRING as determined by the OFFSET and LENGTH parameters. If LENGTH is not specified, then everything from OFFSET to the end of STRING is returned. A negative OFFSET can be used to start from the right side of STRING.
  • uc(STRING) -- Returns a string with every letter of STRING in uppercase. For instance, uc("abcd") returns "ABCD".
  • Ucfirst(STRING) -- Returns a string with the first letter of STRING in uppercase. For instance, ucfirst("abcd") returns "Abcd".

Note As a general rule, if Perl sees a number where it expects a string, the number is quietly converted to a string without your needing to do anything.

Note Some of these functions use the special variable $_ as the default string to work with. More information about $_ can be found in Chapter on Files, and the Chapter Special Variables.

The next few sections demonstrate some of these functions. After seeing some of them work, you'll be able to use the rest of them.

Example: Changing a String's Value

Frequently, I find that I need to change part of a string's value, usually somewhere in the middle of the string. When this need arises, I turn to the substr() function. Normally, the substr() function returns a sub-string based on three parameters: the string to use, the position to start at, and the length of the string to return.

$firstVar = substr("0123BBB789", 4, 3);
print("firstVar = $firstVar\n");

This program prints:

firstVar = BBB

The substr() function starts at the fifth position and returns the next three characters. The returned string can be printed like in the above example, as an array element, for string concatention, or any of a hundred other options.

Things become more interesting when you put the substr() function on the left-hand side of the assignment statement. Then, you actually can assign a value to the string that substr() returns.

$firstVar = "0123BBB789"; substr($firstVar, 4, 3) = "AAA";
print("firstVar = $firstVar\n");

This program prints:

firstVar = 0123AAA789

Example: Searching a String

Another useful thing you can do with strings is search them to see if they have a given sub-string. For example if you have a full path name such as

"C:\\WINDOWS\TEMP\WSREWE.DAT",

you might need to extract the file name at the end of the path. You might do this by searching for the last backslash and then using substr() to return the sub-string.

Note The path name string has double backslashes to indicate to Perl that we really want a backslash in the string and not some other escape sequence, search.pl

$pathName = "C:\\WINDOWS\\TEMP\\WSREWE.DAT";
$position = rindex($pathName, "\\") + 1;
$fileName = substr($pathName, $position);
print("$fileName\n");

This program prints:

WSREWE.DAT

If the third parameter-the length-is not supplied to substr(), it simply returns the sub-string that starts at the position specified by the second parameter and continues until the end of the string specified by the first parameter.

Featured Post

Windows和Ubuntu双系统完全独立的安装方法

http://www.ubuntuhome.com/windows-and-ubuntu-install.html  | Ubuntu Home Posted by Snow on 2012/06/25 安装Windows和Ubuntu双系统时,很多人喜欢先安装windows,然...