入门示例拓展
1. Perl 简单入门
Perl 是一门功能强大的脚本语言,诞生于 20 世纪 80 年代,其思想主要来自其他的编程语言
和工具。Perl 关于文本处理和正则表达式的许多概念都是来自 awk
和 sed
, Perl 可以应用于
多平台, 文本处理能力极其强大, 是 Web 的处理中最常使用的工具。
$ perl
$celsius = 30; # 定义变量
$fahrenheit = ($celsius * 9 / 5) + 32; # 组合一个新的变量
print "$celsius C is $fahrenheit F.\n"; # Prel 中的变量可以直接出现在字符串内
30 C is 86 F. # 输出结果
# Perl 中的循环
$ perl
$count = 10;
while( $count-- > 0)
{
print "$count ";
}
9 8 7 6 5 4 3 2 1 0
# 保存在文本中执行
$ perl -w perlscript # -w 表示以 warning 模式执行该脚本
9 8 7 6 5 4 3 2 1 0
# 正则表达式匹配文本
if($reply =~ m/^[0-9]+$/) { # =~ 连接正则表达式和待搜索的目标字符串
print "only digits\n"; # m/.../ 中的 m 代表尝试进行正则表达式匹配,/ 斜线用来标记界限
}else { # 还可以使用 m/.../i 表示不区分大小写,类似 perl -i 的效果
print "not only digits\n";
}
print "请输入一个数字\n";
$celsius = <STDIN>; # 从用户处接受一个输入
chomp($celsius); # 去掉 $celsius 后面的换行符
if($celsius =~ m/^-?[0-9]+(\.[0-9]*)?$/) {
print "输入正确\n";
}else {
print "输入有误\n";
}
$ perl PerlRegex
# 匹配一行或多行文本
(.*\n)+
# 错综复杂的正则表达式
^([-+]?[0-9]+(\.[0-9]*)?) # 最外面的括号会创建一个变量 s1 来保存
# 而 (\.[0-9]*) 虽然只是用来分组问号限定的对象,也会将它匹配的文本存入 s2
^([-+]?[0-9]+(?:\.[0-9]*)?) # (?:\.[0-9]*) Perl 提供的元字符,表示只用于分组,而不会影响文本的捕获和变量保存
[. ]*和(.*| *) : 可以匹配若干空格符及若干制表符
[.\t]* : 匹配若干个制表符
\s : 匹配所有空白字符,其中包括空格符、制表符、换行符和回车符
2. 使用正则表达式修改文本
- s/regex/replacement/ : 将匹配的
regex
替换为replacement
2.1 替换数据
# 替换匹配文本
$str = "I love Perl Perl";
$str =~ m/Perl/i; # 忽略大小写匹配 Perl, 匹配成功返回 1, 否则 0
$str =~ s/Perl/BASH/g; # 全局替换将 str 中的 Perl 替换为 BASH
$str !~ tr/A-Z/a-z/; # 表示将变量 $str 中的所有大写字母转化为小写字母,如果转化发生了则返回 "0",否则返回 "1"
print "$str";
i love bash bash
# 保留浮点数的小数位
$price = 12.3750000000392; # 因浮点数在计算机的特性, 导致多出来很多小数位
$price =~ s/(\.\d\d[1-9]?)\d*/$1/; # (\.\d\d[1-9]?) 表示保留两位小数点, 当第三位不为 0 时, 也会保留
print "$price\n";
2.2 环视结构添加数据
- 环视结构不匹配任何字符,只匹配文本中的特定位置.
- 环视只是标记位置, 括号也是 “分组但不捕获”, 不会 “占用” 字符
2.2.1 四种类型的环视
类型 | 正则表达式 | 匹配成功条件 |
---|---|---|
肯定顺序环视 | (?=…) | 子表达式能够匹配右侧文本 |
否定顺序环视 | (?!…) | 子表达式不能匹配右侧文本 |
肯定逆序环视 | (?<=…) | 子表达式能够匹配左侧文本, 从右向左看文本, 例如 (?<=d) 如果当前位置的左边是一个数字, 则匹配成功 |
否定逆序环视 | (? | 子表达式不能匹配左侧文本 |
2.2.2 使用案例
(?=Jeffrey)Jeff # 环视的正则表达式
by Jeffrey Friedl. # 可以匹配 (?=Jeffrey)Jeff
by Thome Jefferson. # 不可以匹配, 因为无法匹配环视 (?=Jeffrey)
# 将 Jeffs 替换成 Jeff's
s/Jeffs/Jeff's/g # 全局将 Jeffs 替换为 Jeff's
s/\bJeffs\b/Jeff's/g # 全局替换单词(必须是单词)
s/\b(Jeff)(s)\b/$1'$2/g # 与上一行效果一致
s/\bJeff(?=s\b)/Jeff'/g # 使用环视实现替换, 未尾的 s 不需要替换
s/(?<=\bJeff)(?=s\b)/'/g # 完全使用环视实现, 不替换任何字符, 只插入一个 ' 号
$ perl
$str = "by Jeffs Friedl.";
$str =~ s/(?<=\bJeff)(?=s\b)/'/g;
print "$str";
by Jeff's Friedl. # 输出结果
# 为金额添加分隔逗号
$str = "12345678";
$str =~ s/(?<=\d)(?=(\d\d\d)+$)/,/g; # (?<=\d) 保证左边必须是数字, ?=(\d\d\d) 保证右边是 3 个数字, $ 保证结尾是数字(因为替换过程中会有 , 逗号)
print "$str";
12,345,678
# Text To Html
## 文本文件 file-slurp
This is a sample file.
It has three lines.
That's all.
## 转换脚本
undef $/; # 进入 "file-slurp" 文件读取模式
$text = <>; # 读入命令行指定的第一个文件
$text =~ s/^|$/<p>/mg; # m 表示增加行描点, 保持文件原有行模式, 默认会将文件所有行视为一行
print "$text";
## 执行脚本
$ perl html.perl file-slurp