Perl语言入门指南:从零开始掌握强大的脚本语言

目录

一、Perl简介

Perl语言简介

Perl的历史和发展

Perl的特点和应用领域

本教程目的和结构

二、环境配置

安装Perl解释器

配置编辑器或IDE

三、基本语法

Hello World程序

变量

数据类型

运算符

四、控制结构

条件语句

循环语句

跳转语句

五、子程序和函数

定义和调用子程序

参数传递

返回值

局部变量和全局变量

六、文件操作

文件的读取和写入

文件测试操作

七、正则表达式

正则表达式基础

高级正则表达式

八、模块和包

使用CPAN模块

创建和使用模块

九、面向对象编程

Perl中的面向对象编程基础

继承和多态

十、调试和测试

调试技巧

编写测试

十一、实战案例

案例一:简单文本处理工具

案例二:日志文件分析器

案例三:小型Web爬虫

十二、资源和学习建议

官方文档和教程

社区资源和学习平台

常用工具和库推荐

Perl语言的优势和前景

学习Perl的建议和下一步


一、Perl简介

Perl语言简介

Perl,全称为 Practical Extraction and Report Language(实用提取与报告语言),是由Larry Wall于1987年开发的一种编程语言。最初设计的目的是为了方便文本处理,但随着时间的推移,Perl已发展成为一种功能强大、用途广泛的编程语言,应用于系统管理、Web开发、网络编程、数据库访问等多个领域。

Perl的历史和发展

Perl的起源可以追溯到20世纪80年代,当时Larry Wall在编写UNIX系统管理脚本时,发现现有的工具(如sed和awk)在处理复杂任务时存在局限性,为了解决这些问题,他决定开发一种新工具,这就是Perl语言的雏形。

Perl 1.0于1987年12月18日发布,随着版本的不断更新,Perl的功能和性能也得到了显著提升。Perl 5.0于1994年发布,标志着Perl语言的一个重要里程碑,Perl 5引入了模块化和面向对象编程的支持,使得Perl语言变得更加灵活和强大。时至今日,Perl 5仍然在不断更新和维护,而Perl 6(现称为Raku)则作为一个独立的语言分支,继续发展。

Perl的特点和应用领域

Perl以其灵活性和强大的文本处理能力而闻名,以下是Perl的一些主要特点:

  • 强大的文本处理能力:Perl内置了丰富的正则表达式支持,使其在文本搜索、替换和格式化方面表现出色。
  • 跨平台性:Perl可以运行在几乎所有操作系统上,包括UNIX、Linux、Windows和macOS。
  • 丰富的CPAN模块库:Comprehensive Perl Archive Network(CPAN)是一个包含数万种模块的存储库,几乎涵盖了所有可能的应用场景。
  • 灵活性:Perl语法非常灵活,支持多种编程范式,包括过程式编程、面向对象编程和函数式编程。
  • 高效性:Perl的解释器和编译器设计高效,能够快速执行脚本,处理大量数据。

由于这些特点,Perl广泛应用于以下领域:

  • 系统管理:自动化系统任务、监控系统状态、处理日志文件等。
  • Web开发:CGI脚本、Web应用程序开发。
  • 网络编程:构建网络应用、处理网络协议。
  • 数据库访问:与多种数据库系统交互,执行SQL查询和数据分析。
  • 文本处理:数据清洗、格式转换、日志分析。

本教程目的和结构

本教程旨在为开发者提供一个详细的Perl语言入门指南,即使从未接触过Perl语言的开发者也能通过本教程掌握Perl的基本语法和常用功能。本教程将从环境配置开始,逐步介绍Perl的基本语法、控制结构、文件操作、正则表达式、模块与包、面向对象编程、调试与测试以及实战案例。最后,我们还将提供一些学习资源和建议,帮助读者更深入地学习和应用Perl语言。

二、环境配置

安装Perl解释器

在开始编写Perl代码之前,需要先安装Perl解释器,不同操作系统的安装方法有所不同,以下是各主要操作系统的安装步骤。

在Windows上安装
  • 下载ActivePerl
  • 安装ActivePerl
    • 双击下载的安装包,按照提示完成安装过程,安装过程中,可以选择将Perl添加到系统路径,这样可以在命令行中直接运行Perl命令。
  • 验证安装
    • 打开命令提示符(CMD),输入以下命令验证安装是否成功:
perl -v
    • 如果安装成功,您将看到Perl版本信息。
在macOS上安装

macOS系统通常预装了Perl解释器,但版本可能较旧,建议使用Homebrew进行安装和管理。

  • 安装Homebrew
    • 打开终端,输入以下命令安装Homebrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  • 安装Perl
    • 使用Homebrew安装最新版本的Perl:
brew install perl
  • 验证安装
    • 在终端中输入以下命令验证安装是否成功:
perl -v
在Linux上安装

大多数Linux发行版默认包含Perl解释器。如果需要安装或更新Perl,可以使用包管理器。

  • Debian/Ubuntu
sudo apt-get update
sudo apt-get install perl
  • CentOS/Fedora
sudo yum install perl
  • 验证安装
    • 在终端中输入以下命令验证安装是否成功:
perl -v

配置编辑器或IDE

虽然可以使用任何文本编辑器编写Perl代码,但选择一个支持语法高亮和代码提示的编辑器或IDE可以显著提高开发效率。以下是几种常用的编辑器和配置方法。

常用编辑器介绍
  • Vim
    • Vim是一个强大的文本编辑器,支持多种编程语言的语法高亮和自动补全,可以通过安装Perl插件增强其功能。
    • 安装Perl插件:
vim +PluginInstall +qall
    • 配置语法高亮:
      .vimrc文件中添加以下内容:
syntax on
filetype plugin indent on
  • VSCode
    • Visual Studio Code(VSCode)是一款流行的跨平台编辑器,支持多种编程语言的扩展。
    • 安装Perl插件:
      • 打开VSCode,进入扩展市场,搜索并安装“Perl”插件。
    • 配置代码提示和调试支持。
  • Atom
    • Atom是一款由GitHub开发的开源编辑器,具有高度可定制性。
    • 安装Perl插件:
      • 打开Atom,进入设置,搜索并安装“language-perl”插件。
    • 配置语法高亮和代码自动补全。
配置Perl插件

配置Perl插件可以显著提升编辑器的功能和用户体验,例如,配置VSCode的Perl插件可以启用代码自动补全、错误提示和调试功能。

  • 安装Perl插件
    • 打开VSCode,进入扩展市场,搜索并安装“Perl”插件。
  • 配置代码提示
    • 在VSCode的设置中,启用代码提示和自动补全功能。
  • 配置调试支持
    • 在VSCode中安装“Perl Debug”插件,配置调试环境,可以直接在编辑器中调试Perl代码。

三、基本语法

Hello World程序

让我们从一个简单的Hello World程序开始。创建一个新的Perl文件(如hello.pl),并输入以下代码:

#!/usr/bin/perl
print "Hello, World!\n";
  • #!/usr/bin/perl:这一行被称为shebang,用于指定Perl解释器的路径。
  • print "Hello, World!\n";:使用print函数输出字符串Hello, World!\n表示换行。

保存文件后,在命令行中运行:

perl hello.pl

您将看到输出:

Hello, World!

变量

Perl支持三种主要类型的变量:标量(Scalars)、数组(Arrays)和哈希(Hashes)。

标量(Scalars)

标量是最基本的变量类型,用于存储单个值,如数字或字符串。标量变量以美元符号$开头。

my $name = "John";
my $age = 30;
print "$name is $age years old.\n";
数组(Arrays)

数组用于存储有序的列表。数组变量以@开头。

my @colors = ("red", "green", "blue");
print "The first color is $colors[0].\n";
哈希(Hashes)

哈希用于存储键值对。哈希变量以百分号%开头。

my %ages = ("John" => 30, "Jane" => 25);
print "John is $ages{'John'} years old.\n";

数据类型

Perl的主要数据类型包括数字、字符串和引用,理解这些基本数据类型有助于编写更高效和灵活的代码。

数字和字符串

数字可以是整数或浮点数,Perl会根据上下文自动处理,字符串可以用单引号或双引号表示。

  • 整数和浮点数
my $integer = 42;
my $float = 3.14;
print "Integer: $integer, Float: $float\n";
  • 单引号和双引号
    • 单引号中的字符串会原样输出,不解析转义字符和变量。
my $name = 'Alice';
print 'Hello, $name\n';  # 输出:Hello, $name\n
    • 双引号中的字符串会解析转义字符和变量。
my $name = "Alice";
print "Hello, $name\n";  # 输出:Hello, Alice
引用和上下文

引用是指向其他数据结构(如标量、数组、哈希等)的指针,引用的使用使得可以在数据结构之间共享数据或传递复杂数据结构。

  • 创建和解引用标量引用
my $var = 10;
my $ref = \$var;
print "Reference: $ref, Value: $$ref\n";  # 输出:Reference: SCALAR(0x...), Value: 10
  • 创建和解引用数组引用
my @array = (1, 2, 3);
my $array_ref = \@array;
print "First element: $array_ref->[0]\n";  # 输出:First element: 1
  • 创建和解引用哈希引用
my %hash = (foo => 1, bar => 2);
my $hash_ref = \%hash;
print "Value of foo: $hash_ref->{foo}\n";  # 输出:Value of foo: 1

运算符

Perl支持多种运算符,包括数学运算符、字符串运算符、逻辑运算符和比较运算符。

数学运算符

数学运算符用于数值计算:

  • 加法、减法、乘法、除法、取模
my $sum = 5 + 3;     # 8
my $difference = 5 - 3;  # 2
my $product = 5 * 3;  # 15
my $quotient = 5 / 3;  # 1.6667
my $remainder = 5 % 3;  # 2
print "$sum, $difference, $product, $quotient, $remainder\n";
字符串运算符

字符串运算符用于字符串连接和重复:

  • 连接运算符(.)和重复运算符(x
my $hello = "Hello";
my $world = "World";
my $greeting = $hello . ", " . $world . "!";  # "Hello, World!"
my $repeat = "abc" x 3;  # "abcabcabc"
print "$greeting\n$repeat\n";
逻辑运算符

逻辑运算符用于布尔逻辑运算:

  • 与(&&)、或(||)、非(!
my $true = 1;
my $false = 0;
print "True and False: " . ($true && $false) . "\n";  # 0
print "True or False: " . ($true || $false) . "\n";  # 1
print "Not True: " . (!$true) . "\n";  # 0
比较运算符

比较运算符用于数值和字符串比较:

  • 数值比较
my $a = 5;
my $b = 3;
print "Equal: " . ($a == $b) . "\n";  # 0
print "Not equal: " . ($a != $b) . "\n";  # 1
print "Greater than: " . ($a > $b) . "\n";  # 1
print "Less than: " . ($a < $b) . "\n";  # 0
    • 相等(==),不等(!=),大于(>),小于(<),大于等于(>=),小于等于(<=
  • 字符串比较
my $str1 = "apple";
my $str2 = "orange";
print "Equal: " . ($str1 eq $str2) . "\n";  # 0
print "Not equal: " . ($str1 ne $str2) . "\n";  # 1
print "Greater than: " . ($str1 gt $str2) . "\n";  # 0
print "Less than: " . ($str1 lt $str2) . "\n";  # 1
    • 相等(eq),不等(ne),大于(gt),小于(lt),大于等于(ge),小于等于(le

四、控制结构

条件语句

条件语句用于根据条件执行不同的代码块,Perl支持多种条件语句,包括ifunlesselsif

if/else
my $age = 20;
if ($age >= 18) {
    print "You are an adult.\n";
} else {
    print "You are a minor.\n";
}
unless

unless语句与if语句相反,只有在条件为假时才执行代码块。

my $status = 0;
unless ($status) {
    print "Status is false.\n";
}
elsif

elsif用于在ifelse之间添加多个条件。

my $score = 85;
if ($score >= 90) {
    print "Grade: A\n";
} elsif ($score >= 80) {
    print "Grade: B\n";
} else {
    print "Grade: C\n";
}

循环语句

循环语句用于重复执行代码块,Perl支持多种循环语句,包括forforeachwhileuntil

for

for循环用于重复执行代码块,直到满足条件。

for (my $i = 0; $i < 5; $i++) {
    print "Iteration $i\n";
}
foreach

foreach循环用于遍历数组或列表中的每个元素。

my @colors = ("red", "green", "blue");
foreach my $color (@colors) {
    print "Color: $color\n";
}
while

while循环用于在条件为真时重复执行代码块。

my $count = 0;
while ($count < 5) {
    print "Count: $count\n";
    $count++;
}
until

until循环与while循环相反,在条件为假时重复执行代码块。

my $count = 0;
until ($count >= 5) {
    print "Count: $count\n";
    $count++;
}

跳转语句

跳转语句用于控制循环的执行,Perl支持多种跳转语句,包括nextlastredo

next

next用于跳过当前迭代,进入下一次循环。

for (my $i = 0; $i < 5; $i++) {
    next if $i == 2;
    print "Iteration $i\n";
}
last

last用于立即退出循环。

for (my $i = 0; $i < 5; $i++) {
    last if $i == 3;
    print "Iteration $i\n";
}
redo

redo用于重新开始当前迭代,而不检查循环条件。

my $count = 0;
while ($count < 5) {
    $count++;
    print "Count: $count\n";
    redo if $count == 3;
}

五、子程序和函数

子程序和函数是Perl中用于组织代码、提高复用性的重要结构。

定义和调用子程序

子程序可以通过sub关键字定义,并通过子程序名调用。

sub greet {
    my ($name) = @_;
    print "Hello, $name!\n";
}

greet("Alice");

参数传递

子程序可以通过参数传递数据。参数在子程序内部以数组@_的形式访问,可以通过列表解构获取参数值。

sub add {
    my ($a, $b) = @_;
    return $a + $b;
}

my $sum = add(5, 3);
print "Sum: $sum\n";  # 输出:Sum: 8

返回值

子程序可以通过return关键字返回值。如果没有显式使用return,子程序将返回最后一个表达式的值。

sub multiply {
    my ($a, $b) = @_;
    return $a * $b;
}

my $product = multiply(4, 5);
print "Product: $product\n";  # 输出:Product: 20

局部变量和全局变量

局部变量使用my关键字定义,只在子程序或代码块内部有效。全局变量在程序的任何地方都可以访问。

my $global = 10;

sub example {
    my $local = 5;
    print "Local: $local\n";    # 输出:Local: 5
    print "Global: $global\n";  # 输出:Global: 10
}

example();
print "Global outside: $global\n";  # 输出:Global outside: 10

六、文件操作

文件操作是编程中的常见任务,Perl提供了丰富的函数来处理文件的读取和写入。

文件的读取和写入

打开和关闭文件

使用open函数打开文件,使用close函数关闭文件。

open(my $fh, '<', 'input.txt') or die "Could not open file: $!";
# ... 读取或写入操作 ...
close($fh);
读取文件内容

使用<FH>读取文件内容,或使用readline函数。

open(my $fh, '<', 'input.txt') or die "Could not open file: $!";
while (my $line = <$fh>) {
    print $line;
}
close($fh);
写入文件内容

使用>模式打开文件进行写入,使用>>模式追加写入。

open(my $fh, '>', 'output.txt') or die "Could not open file: $!";
print $fh "Hello, World!\n";
close($fh);

文件测试操作

Perl提供了多种文件测试运算符来检查文件的属性。

文件测试运算符

常用的文件测试运算符包括:

  • -e:文件是否存在
  • -r:文件是否可读
  • -w:文件是否可写
  • -x:文件是否可执行
  • -z:文件是否为空
my $file = 'example.txt';
if (-e $file) {
    print "File exists\n";
}
if (-r $file) {
    print "File is readable\n";
}
if (-w $file) {
    print "File is writable\n";
}
if (-x $file) {
    print "File is executable\n";
}
if (-z $file) {
    print "File is empty\n";
}
文件信息获取

使用stat函数获取文件的详细信息。

my $file = 'example.txt';
my @info = stat($file);
print "File size: $info[7] bytes\n";
print "Last modified: " . localtime($info[9]) . "\n";

七、正则表达式

正则表达式是Perl的一大特色,用于字符串匹配、搜索和替换。

正则表达式基础

模式匹配

使用=~运算符和匹配操作符m//进行模式匹配。

my $text = "The quick brown fox";
if ($text =~ /quick/) {
    print "Match found!\n";
}
替换操作

使用替换操作符s///进行字符串替换。

my $text = "The quick brown fox";
$text =~ s/quick/slow/;
print "$text\n";  # 输出:The slow brown fox
常用元字符

常用的正则表达式元字符包括:

  • .:匹配任意单个字符
  • *:匹配前一个字符0次或多次
  • +:匹配前一个字符1次或多次
  • ?:匹配前一个字符0次或1次
  • \d:匹配任意数字字符
  • \w:匹配任意字母或数字字符
  • \s:匹配任意空白字符
my $text = "abc123";
if ($text =~ /\d+/) {
    print "Contains digits\n";
}

高级正则表达式

捕获组和非捕获组

使用圆括号()创建捕获组,使用(?:)创建非捕获组。

my $text = "Name: John Doe";
if ($text =~ /Name: (\w+) (\w+)/) {
    print "First name: $1, Last name: $2\n";  # 输出:First name: John, Last name: Doe
}
前瞻和后顾

使用前瞻(?=...)和后顾(?<=...)进行复杂匹配。

my $text = "abc123def";
if ($text =~ /(?<=abc)\d+(?=def)/) {
    print "Matched digits between abc and def\n";
}
正则表达式修饰符

常用的修饰符包括:

  • i:不区分大小写
  • g:全局匹配
  • m:多行匹配
my $text = "abc\n123\nabc";
$text =~ s/abc/XYZ/gi;
print "$text\n";  # 输出:XYZ\n123\nXYZ

八、模块和包

Perl通过模块和包实现代码的重用和组织,模块是Perl代码的集合,包是模块的命名空间。

使用CPAN模块

CPAN(Comprehensive Perl Archive Network)是一个包含大量Perl模块的存储库。

安装CPAN模块

使用CPAN客户端安装模块。

cpan install Text::CSV
常用CPAN模块介绍
  • Text::CSV:处理CSV文件
  • LWP::UserAgent:Web客户端
  • DBI:数据库接口

创建和使用模块

创建自定义模块

创建一个简单的Perl模块,保存为MyModule.pm

package MyModule;
use strict;
use warnings;

sub hello {
    print "Hello from MyModule!\n";
}

1;  # 必须以返回真值结束
导入和使用模块

在主程序中导入和使用自定义模块。

use MyModule;
MyModule::hello();

九、面向对象编程

Perl支持面向对象编程,通过包和引用实现。

Perl中的面向对象编程基础

创建类和对象

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

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;
属性和方法

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

use Person;

my $person = Person->new(name => "Alice");
$person->greet();  # 输出:Hello, I am Alice

继承和多态

子类和超类

创建一个子类继承自超类。

package Employee;
use base 'Person';

sub new {
    my ($class, %args) = @_;
    return $class->SUPER::new(%args);
}

sub work {
    my ($self) = @_;
    print "$self->{name} is working\n";
}

1;
方法重载

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

use Employee;

my $employee = Employee->new(name => "Bob");
$employee->greet();  # 输出:Hello, I am Bob
$employee->work();   # 输出:Bob is working

十、调试和测试

调试和测试是确保代码质量的重要步骤。

调试技巧

使用警告和严格模式

使用use warningsuse strict启用警告和严格模式,帮助发现潜在问题。

use strict;
use warnings;

my $x = 10;
print $x;
使用Perl调试器

使用Perl调试器调试代码。

perl -d script.pl

编写测试

Perl提供了多种测试模块,最常用的是Test::Simple和Test::More。

Test::Simple模块

Test::Simple模块提供了简单的测试功能,适用于基本测试需求。

use Test::Simple tests => 2;

ok(1 + 1 == 2, 'Addition works');
ok('Hello' eq 'Hello', 'String comparison works');
Test::More模块

Test::More模块提供了更丰富的测试功能,适用于复杂的测试需求。

use Test::More tests => 3;

is(1 + 1, 2, 'Addition test');
is('foo' . 'bar', 'foobar', 'String concatenation test');
ok(defined $some_var, 'Variable is defined');

通过这些测试模块,开发者可以编写单元测试,确保代码的正确性和稳定性。

十一、实战案例

通过实际案例,展示Perl在实际应用中的强大功能。

案例一:简单文本处理工具

设计一个简单的文本处理工具,读取文件,处理文本并输出结果。

文件内容(input.txt)

Hello, World!
Perl is powerful.
Text processing is fun.

Perl脚本(text_processor.pl)

use strict;
use warnings;

my $input_file = 'input.txt';
my $output_file = 'output.txt';

open(my $in_fh, '<', $input_file) or die "Could not open '$input_file' $!";
open(my $out_fh, '>', $output_file) or die "Could not open '$output_file' $!";

while (my $line = <$in_fh>) {
    $line =~ s/(\w+)/\U$1/g;  # 将单词转换为大写
    print $out_fh $line;
}

close($in_fh);
close($out_fh);

print "Text processing complete. Check 'output.txt'.\n";

案例二:日志文件分析器

设计一个日志文件分析器,提取错误信息并生成报告。

日志文件(log.txt)

INFO: Application started
ERROR: Failed to connect to database
INFO: User logged in
ERROR: Invalid user input
INFO: Application terminated

Perl脚本(log_analyzer.pl)

use strict;
use warnings;

my $log_file = 'log.txt';
my $report_file = 'error_report.txt';

open(my $log_fh, '<', $log_file) or die "Could not open '$log_file' $!";
open(my $report_fh, '>', $report_file) or die "Could not open '$report_file' $!";

print $report_fh "Error Report:\n";
print $report_fh "-------------\n";

while (my $line = <$log_fh>) {
    if ($line =~ /ERROR: (.+)/) {
        print $report_fh "$1\n";
    }
}

close($log_fh);
close($report_fh);

print "Error report generated. Check 'error_report.txt'.\n";

案例三:小型Web爬虫

设计一个简单的Web爬虫,抓取网页内容并提取特定信息。

Perl脚本(web_crawler.pl)

use strict;
use warnings;
use LWP::Simple;
use HTML::TreeBuilder;

my $url = 'http://example.com';
my $content = get($url);

die "Couldn't get $url" unless defined $content;

my $tree = HTML::TreeBuilder->new_from_content($content);

my @titles = $tree->look_down(_tag => 'title');
foreach my $title (@titles) {
    print "Title: " . $title->as_text . "\n";
}

$tree->delete;

十二、资源和学习建议

官方文档和教程

官方文档是学习Perl的最佳资源,Perl官方文档(perldoc.perl.org)提供了详细的语言参考和使用手册。

社区资源和学习平台

  • Perl Monks(perlmonks.org):一个活跃的Perl社区,提供问题解答和讨论。
  • Stack Overflow(stackoverflow.com):一个编程问答社区,包含大量关于Perl的问题和答案。
  • CPAN(cpan.org):Comprehensive Perl Archive Network,包含大量的Perl模块和库。

常用工具和库推荐

  • Strawberry Perl:适用于Windows的Perl环境,包含所有必要的工具。
  • ActivePerl:ActiveState提供的Perl发行版,适用于多种操作系统。
  • Padre:Perl IDE,提供集成开发环境。

Perl语言的优势和前景

Perl以其灵活性和强大的文本处理能力而著称,广泛应用于系统管理、Web开发、网络编程、数据库访问等领域。尽管近年来其他语言的流行度有所上升,Perl在特定领域仍然具有重要地位,尤其是在处理复杂文本和自动化任务方面。

学习Perl的建议和下一步

  • 实践练习:通过编写小型项目和工具,实践所学知识。
  • 参与社区:加入Perl社区,参与讨论和项目,提高编程技能。
  • 持续学习:关注Perl的最新发展和模块更新,保持技术的前沿性。

本主页会定期更新,为了能够及时获得更新,敬请关注我:点击左下角的关注。也可以关注公众号:请在微信上搜索公众号“AI与编程之窗”并关注,或者扫描以下公众号二维码关注,以便在内容更新时直接向您推送。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI与编程之窗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值