Perl编程语言简介

文章目录

  • 前言
  • 基础语法
    • [一. 变量](#一. 变量)
      • [1. 标量](#1. 标量)
      • [2. 数组](#2. 数组)
      • [3. 哈希](#3. 哈希)
    • [二. 控制结构](#二. 控制结构)
      • [1. 条件语句](#1. 条件语句)
      • [2. 循环语句](#2. 循环语句)
    • [三. 自定义函数与作用域](#三. 自定义函数与作用域)
    • [四. 文件读写](#四. 文件读写)
    • [五. 正则表达式](#五. 正则表达式)
      • [1. 模式匹配](#1. 模式匹配)
      • [2. 替换](#2. 替换)
    • [六. 模块和包](#六. 模块和包)
    • [七. 面向对象的编程](#七. 面向对象的编程)
  • 总结

前言

Perl(Practical Extraction and Report Language)是一种高级编程语言,由拉里·沃尔(Larry Wall)于1987年创建。作为一种多用途的脚本语言,Perl在文本处理领域表现卓越,特别是在系统管理、网络编程和Web开发方面有广泛的应用。Perl的设计哲学旨在提高工作效率,它将多种编程范式(过程式、面向对象、函数式)结合在一起,形成了一个功能强大的工具集。

基础语法

一. 变量

Perl 中的三种基本数据类型是标量(scalar)、数组(array)和哈希表(hash),它们是构建Perl程序的基石。

1. 标量

标量(Scalar) 是单个的数据单位,它可以是数字、字符串,甚至是指向数组或哈希表的引用。标量变量总是以 $ 符号开始。

代码如下(示例):

c 复制代码
my $scalar = 42;        # 整数标量
my $name = "Alice";    # 字符串标量

2. 数组

数组(Array) 是一系列数据的有序集合,以特定的顺序排列,可以通过数字索引来访问。数组变量以 @ 符号开始。访问数组的单个元素使用数字索引,如 print $array0; 将打印数组@array的第一个元素。

代码如下(示例):

c 复制代码
my @array = (1, 2, 3, 4, 5); # 数字数组
my @fruits = ("apple", "banana", "cherry"); # 字符串数组
# 访问数组元素
print @fruits; # 输出数组所有元素
print $fruits[0]; # 输出 apple

3. 哈希

哈希表(Hash) 是键值对(key-value)的集合,每个键都唯一对应一个值。哈希表变量以 % 符号开始。使用键来访问哈希表中的值,如下所示print $hash{'two'}; 将输出 2 。

代码如下(示例):

c 复制代码
my %hash = ('one' => 1, 'two' => 2, 'three' => 3);
# 访问哈希中的元素
print %hash; # 输出哈希的键值对
print $hash{'two'}; #输出 2 

二. 控制结构

Perl中的控制流主要包括if、unless、while 、 until 、 for 、 foreach 和 do-while等命令。

1. 条件语句

在Perl中,条件语句用于根据不同的条件执行不同的代码块。最常用的条件语句是 if 、 unless 、 elsif 和 else。

语法:

c 复制代码
if (condition) {
  # 条件为真时执行的代码
} elsif (another_condition) {
  # 条件为假且另一个条件为真时执行的代码
} else {
  # 所有条件都不满足时执行的代码
}

if 语句在条件满足(即其值为真)时执行其后的代码块。 unless 则正好相反,在条件不满足时执行代码块。可以使用 else 语句在条件失败时执行替代的代码块。 elsif 允许你链式连接多个条件判断。

代码如下(示例):

c 复制代码
# if语句的使用示例
if ($a > $b) {
    print "a is greater than b\n";
} 
# unless语句的使用示例
unless ($a <= $b) {
    print "a is not less than or equal to b\n";
}
# 条件赋值的使用示例
my $max = $a > $b ? $a : $b;

2. 循环语句

Perl 提供了几种循环语句,包括 while 、 until 、 for 、 foreach 和 do-while 。

语法:

c 复制代码
while (condition) {
  # 循环体
}
until (condition) {
  # 循环体
}
for (my $i = 0; $i < 10; $i++) {
  # 循环体
}
foreach my $element (@array) {
  # 循环体
}
do {
  # 循环体
} while (condition);

while 循环在条件为真时重复执行代码块,而 until 则在条件为假时执行。 for 和 foreach 循环常用于遍历数组或列表。 do-while 循环至少执行一次循环体,之后再检查条件。

代码如下(示例):

c 复制代码
# for循环遍历数组
for (my $i = 0; $i < @array; $i++) {
    print "$array[$i]\n";
}
# foreach循环遍历数组
foreach my $element (@array) {
    print "$element\n";
}
# while循环的使用
while ($i < 10) {
    print "The current value of i is $i\n";
    $i++;
}

三. 自定义函数与作用域

perl中的子程序其实就是自定义函数。它使用sub关键字开头 ,表示声明一个子程序。子程序(Subroutine)是 Perl 语言中实现代码重用和结构化编程的基本单元。通过定义和调用子程序,可以将复杂的任务分解成多个可管理的小部分,从而提高代码的清晰度和可维护性。

语法:

c 复制代码
sub 函数名{
    代码语句;
        ...
    代码语句;
}

Perl中的子程序中可以定义、引用、修改全局变量 ,也可以用my定义局部变量。

一般情况下,调用 我们自定义的子程序时,都使用&符号 ,有时候还要带上括号传递参数。

但有时候,&符号和括号是可以省略的。主要的规则是:

  1. 只有子程序定义语句在子程序调用语句前面,才可以省略括号
  2. 当使用了括号,perl已经知道这就是一个子程序调用,这时可以省略&也可以不省略&
  3. 不能省略&的情况比较少。基本上,只要子程序名称不和内置函数同名,或者有特殊需求时(如需要明确子程序的名称时,如defined(&mysub)),都可以省略&
  4. 不能在使用了&、有参数传递的情况下,省略括号
  5. 最安全、最保险的调用方式是:
    有参数时:&subname(arg1,arg2),即不省略&和括号
    无参数时:&subname

代码如下(示例):

c 复制代码
# 定义一个函数
sub my_function {
    my ($param1, $param2) = @_;  # 从参数列表中获取参数
    my $local_variable = "I'm local";
    print "In my_function, parameter 1 is $param1\n";
    print "In my_function, parameter 2 is $param2\n";
    print "In my_function, local variable is $local_variable\n";
}
 
# 调用函数
&my_function("Hello", "World");

#结果
    In my_function, parameter 1 is Hello
    In my_function, parameter 2 is World
    In my_function, local variable is I'm local

Perl子程序除了可以直接操作变量,还可以传递参数,调用子程序时传递的参数会传入子程序,它们存储在一个特殊的数组变量@_中 ,@_数组只在每个子程序执行期间有效,每个子程序的@_都互不影响。@ARGV是Perl默认用来接收参数的数组,可以有多个参数, A R G V 0 是表示接收到的第一个参数, ARGV0是表示接收到的第一个参数, ARGV0是表示接收到的第一个参数,ARGV1表示第二个。
@_是子过程默认的参数列表,在子过程内使用。
@ARGV是整个程序的默认参数列表,在子过程外使用。

代码如下(示例):

c 复制代码
#!/usr/bin/perl

sub my_subroutine {
    my ($arg1, $arg2) = @_;
    
    print "arg1: $arg1\n";
    print "arg2: $arg2\n";
}

my_subroutine($ARGV[0], $ARGV[1]);

假设将上述代码保存为test.pl,然后在命令行中运行:perl test.pl hello world ,输出将会是:

arg1: hello

arg2: world

子程序可以通过 return 关键字返回值。

代码如下(示例):

c 复制代码
sub add {
    my ($a, $b) = @_;
    return $a + $b;
}
 
my $sum = add(3, 4);
print "Sum: $sum\n";

Perl默认所有变量为Package variables,为全局变量,这意味着程序的任何其他部分,甚至在其他文件里定义的子程序,都能影响和修改变量的值。在一定程度上讲,这样是"不安全"的。

自Perl 5以后,增加了新的非全局变量,也称为词法变量、私有变量、局部变量,或称为my变量。例如my a;就定义了一个局部变量a,它的作用域是当前块(Block),通俗地讲就是大括号里面,如果没有大括号就是从定义的地方开始到程序结束,例如该函数。

四. 文件读写

Perl使用 open() 函数来打开文件,并可选地指定文件的模式,如读取、写入或追加。使用完毕后,应通过 close() 函数来关闭文件句柄,以确保数据被正确地写入和文件资源被释放。

代码如下(示例):

c 复制代码
# 打开文件用于读取
open(my $fh, "<", "input.txt") or die "无法打开文件: $!";
# 读取文件内容到数组
my @lines = <$fh>;
# 关闭文件句柄
close($fh);
 
# 打开文件用于写入
open(my $fh, ">", "output.txt") or die "无法打开文件: $!";
# 写入内容到文件
print $fh "写入的内容\n";
# 关闭文件句柄
close($fh);

使用 open() 函数,第一个参数是文件句柄( fh ),第二个参数是模式( **"\<" 表示读取, "\>" 表示写入**)。第三个参数是文件名。使用 die() 函数处理可能的错误, ! 变量包含了系统调用的错误信息。使用文件句柄 $fh 读取和写入文件。读取时, < > 操作符会将文件内容读入到数组 @lines 。使用 close() 函数关闭文件句柄,释放资源。

代码如下(示例):

c 复制代码
# 遍历当前目录中的所有文件和文件夹
foreach my $file (glob("*.txt")) {
    # 检查文件是否存在
    if (-e $file) {
        # 检查文件是否可读
        if (-r $file) {
            print "可读: $file\n";
        }
    }
}

glob() 函数返回当前目录下所有 .txt 文件,并存入数组 @file 。使用 foreach 循环遍历这些文件。if (-e file) 语句检查文件是否存在。if (-r file) 语句检查文件是否可读。

五. 正则表达式

特殊字符叫做元字符,比如点号".",它是任何单字符的通配符,如果要表示点号本身需要在前面加上反斜杠"\"。常用的匹配主要有:

. 匹配除换行符外的任意单个字符。

\d 匹配任意数字字符。

\s 匹配任意空白字符。

\w 匹配任意字母数字字符。

^表示字符串的开头。

$表示字符串的结尾。

* 表示前面的字符可以出现零次或多次。

  • 表示前面的字符可以出现一次或多次。

? 表示前面的字符可以出现零次或一次。

{n} 表示前面的字符恰好出现n次。

{n,} 表示前面的字符至少出现n次。

{n,m} 表示前面的字符至少出现n次,但不超过m次。

1. 模式匹配

使用=~运算符和匹配操作符m//进行模式匹配(m可以忽略不写)。

用圆括号()来表示分组,括号里的内容表示整体。使用圆括号可以对部分字符进行引用。

代码如下(示例):

c 复制代码
my $text = "Name: John Doe";
if ($text =~ /Name: (\w+) (\w+)/) {
    print "First name: $1, Last name: $2\n";  
}

# 输出
First name: John, Last name: Doe

2. 替换

使用=~运算符和替换操作符s///进行字符串替换。常用的修饰符包括:

i:不区分大小写

g:全局匹配

代码如下(示例):

c 复制代码
my $text = "abc\n123\nabc";
$text =~ s/abc/XYZ/gi;
print "$text\n";  

# 输出
XYZ\n123\nXYZ

六. 模块和包

模块(Module)是 Perl 中组织和重用代码的更高级单位。它们通常用于封装函数、变量和其他资源,以便在多个程序中共享。Perl 模块是包含 Perl 代码的文件,通常以 .pm 扩展名命名。模块文件中的包(Package)定义了模块的命名空间,防止命名冲突。导入模块使用 use 语句,它会告诉Perl在编译阶段就加载指定的模块。

模块定义代码如下(示例):

c 复制代码
# Example.pm
package Example;
 
 #strict 模块强制要求变量必须声明,而 warnings 模块允许发出警告,以帮助识别代码中的潜在问题
use strict;
use warnings;
 
sub hello {
    print "Hello from Example module!\n";
}
 
1; 
# 模块必须返回 true 值

模块调用代码如下(示例):

c 复制代码
use Example;
Example::hello();

另外,模块的文件路径应与包名一致,以双冒号 :: 分隔的包名对应目录结构。例如,My::Module 模块应保存在 My/Module.pm 文件中。

七. 面向对象的编程

创建一个简单的类和对象。

代码如下(示例):

c 复制代码
package Person;
use strict;
use warnings;
 
sub new {
    my ($class, %args) = @_;
    return bless \%args, $class;
}
 
sub greet {
    my ($self) = @_;
    print "Hello, I am $self->{name}\n";
}
 
1;

在主程序中创建对象并调用方法。

代码如下(示例):

c 复制代码
use Person;
 
my $person = Person->new(name => "Alice");
$person->greet();  

#输出
Hello, I am Alice

总结

Perl以其灵活性和强大的文本处理能力而闻名,在系统管理、网络编程和Web开发方面有广泛的应用。

相关推荐
蒸蒸yyyyzwd4 小时前
AI应用相关可能的面试问题
笔记
叼烟扛炮5 小时前
[Git 实战] 学习笔记:从生成 SSH 密钥到解决 TortoiseGit 推送报错全指南
linux·运维·笔记·git·学习
蒸蒸yyyyzwd6 小时前
学习笔记 八股手撕
笔记·学习
揣一尾游鱼yu7 小时前
Spring上(IOC)笔记
java·笔记·spring·ioc
小李不想当小白9 小时前
BKP备份寄存器与RTC实时时钟(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
瑞码空间11 小时前
JSP与Servlet核心开发与CRUD实战笔记
java·笔记·servlet·jsp
La Pulga11 小时前
【FreeRTOS源码学习笔记】链表的实现
数据结构·笔记·stm32·mcu·链表·嵌入式·freertos
wuyoutrans14 小时前
以色列专利OA答复翻译,重点要避开哪些坑?
笔记
宝绿特塑业再生科技14 小时前
HDPE再生颗粒户外家具表面粉化机理与改性技术全解析
笔记·户外家具·再生塑料·塑木桌椅
凉、介14 小时前
深入理解 ARMv7-A | Generic Timer
笔记·学习·嵌入式·arm