ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: figfig

[原创] 在vba里使用PERL

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2010-5-6 08:49 | 显示全部楼层
本帖已被收录到知识树中,索引项:脚本语言应用
2.2 qw快捷方式

qw表示“被括引的单词(quoted words)”,用于将一些字符序列赋值给列表或数组。

譬如要将fred, barney, betty,wilma和dino赋值给数组array,如果不用qw快捷方式,则需@array = ("fred", "barney", "betty", "wilma", "dino");这样需要键入大量的双引号。如果使用qw,则为@array = qw /fred barney betty wilma dino /;

注意qw快捷方式后面使用的分隔符是任意的,可以使用//,也可以使用!!或<>等,只要这两个匹配即可。
Sub perl()

Set x = CreateObject("scriptcontrol")
x.Language = "perlscript"
x.eval "@array = qw /fred barney betty wilma dino /;"
MsgBox x.eval("@array[4]")
End Sub

TA的精华主题

TA的得分主题

发表于 2010-5-6 08:59 | 显示全部楼层
报名、学习。谢谢大师!

TA的精华主题

TA的得分主题

 楼主| 发表于 2010-5-6 09:01 | 显示全部楼层
本章讲述了散列(hash)的概念、访问方法及针对散列的一些函数


1.散列的概念

散列类似于数组,与数组相同的是它可以含有任意数目的值并随意读取它们;与数组不同的是,在散列中,使用的索引是字符串(这里成为键(key))而不是数值,即使用名字来查找对应的值。键是任意字符串,在某个确定的散列中,它的值是唯一的。

键和值(value)都是任意的标量,但键总是被转成字符串。


2.访问方法

和标量、数组一样,散列拥有独立的命名空间。

访问散列中的元素,可以使用如下的语法:

$hash{$some_key}

访问整个散列,使用百分号(%)做前缀

%hash


3.赋值

为了方便起见,可以将散列转换为一个列表,并转换回来。给散列赋值是一个列表上下文,这个表由键-值对组成:

%some_hash={"foo",35,"bar",12.4,2.5,"hello","wilma",1.72e30,"betty","byen");

在这种赋值中,不太容易分辨键和值的对应关系,在Perl中,可以使用大箭头(=>)来表示键和值的对应关系,如下所示:
%some_hash={
"foo" => 35,
"bar" => 12.4,
2.5 => "hello",
"wilma" => 1.72e30,
"betty" => "byen",
);
散列(在列表上下文中)的值是一个简单的键-值对列表:
@any_array = %some_hash;
上式称之为展开(unwind)散列,展开时不能预知键-值对的顺序,但是键和值总是对应的。


4.散列函数
4.1 keys和values函数
my @k = keys %hash; # 获得该散列中所有的键
my @v = values %hash; #获得该散列中所有的数值

在一个标量上下文中,这些函数给出散列中的元素(键-值对)个数
my $count = keys %hash;

4.2 each函数
each函数用于遍历一个散列,每次返回一个键-值对作为一个二元素列表。实际情况下,一般只在while循环中使用each,如下所示:
while ( ($key,$value) = each %hash) {
print "$key => $valuen";
}
上面这个例子用于遍历散列%hash,每次取一个键-值对,并将该键-值对赋给($key,$value)列表。当遍历完该散列时,($key,$value)=(undef,undef),此时,while循环条件不成立,则循环结束。

为了遍历散列,也可以使用foreach和keys函数相结合的方式,采用这种方式,还可以在遍历时对散列进行排序,如下所示:
foreach $key (sort keys %hash) {
...
}

4.3 exists函数
要查看某键是否在散列中,可以使用exists函数,它在键存在时返回真,不论相应的值是真还是假:
if (exists $books{"dino"}) {
...
}

4.4 delete函数
delete函数从散列中删去指定的键(和相应的值)。(如无此键,它的任务就结束了。此时既无警告,也没有错误消息。)
my $person = "betty";
delete $books{$person}; #撤销$person的借书卡

4.5 reverse操作符
使用reverse操作符可以生成一个逆散列,即原先的键变为新散列中的值,原先的值变成新散列中的键。如果原散列中的值不是唯一的(即值之间有重复),则无法判断新的散列中某个键对应的是哪个值。因此,使用reverse操作符变换散列一般只适用于键和值都是唯一(不重复)的散列。

TA的精华主题

TA的得分主题

发表于 2010-5-6 09:04 | 显示全部楼层

学习很高深呢不容易

学习很高深呢不容易

TA的精华主题

TA的得分主题

 楼主| 发表于 2010-5-6 09:06 | 显示全部楼层
《Learning Perl》学习笔记 -- 第七章 正则表达式的概念
笔者注:用过几次正则表达式后,为它的强大与灵活所折服,打算再深入研究一下,本书推荐了Jeffrey E.F.Friedl编著的《Mastering Regular Expression》,已经从图书馆借的,有空研读一下:P


本章主要介绍了正则表达式的概念,还介绍了正则表达式的一些基本要素,如元字符、数量符、模式分组、选择等。


1.正则表达式的概念

书中这段讲的很好,简明易懂,我就照抄了,呵呵

正则表达式(regular expression),在Perl中经常被成为模式(pattern),是与一个给定字符串匹配或不匹配的模板。也就是说,有无限数量可能的文本字符串。一个给定的模式把这个无限集合分成两个组:匹配的组和不匹配的组。不能有“可能”、“也许”、“似乎”之类的匹配:必须是要么匹配,要么不匹配。

正则表达式强调的是一种精确的概念。


2.使用简单的模式

要比较一个模式(正则表达式)和$_的内容,只需把模式放在一对斜杠(/)之间,如下所示:

$_ = "yabba dabba doo";

if (/abba/) {

...

}

表达式/abba/在$_中寻找这个四字符的字符串,如果找到了,返回真;否则,返回假。

这是一种默认模式,在下一章中将介绍如何在一个指定的变量中匹配特定的模式。

所有可以放在双引号字符串中的常见反斜杠转义符都可以被用在模式中。


3.元字符

正则表达式中有一组具有特殊意义的特殊字符,叫做元字符(metacharater)。

句号(.):匹配除了换行符(n)以外的任何单个字符;

反斜杠(\):在任何元字符前加一个反斜杠都会使得它不再特别;\.表示一个句号,\\表示一个反斜杠;


4.数量符(quantifier)

星号(*):匹配前面的条目零次或多次;

加号(+):匹配前面的条目一次或多次;

问号(?):匹配前面的条目零次或一次,即前面的条目是可选的;

这三个数量符都必须跟在某些东西的后面,因为它们就是表示前面的条目可能重复多少次。


5.模式中的分组

在正则表达式中,使用小括号("()")进行分组。譬如,模式/(fred)+/匹配类似于fredfredfred的字符串。


6.选择

竖线表示要么是左侧匹配,要么是右侧匹配,此时读做“或”,也就是说,如果模式中竖线左侧的部分不能匹配,那么右侧的部分就有机会进行匹配。


7.一个模式测试程序

该章给了一个有趣的模式测试程序,可以用来测试自己写的正则表达式是否可以如自己所愿、匹配需要匹配的东西。

#!/usr/bin/perl

while (<>) { #一次得到一个输入行

chomp;

if (/YOUR_PATTERN_GOES_HERE/) {

print "Matched: $`<$&>$'\n"; # <>之间、$后面的是与字符(&)

} else {

print "No match.\n";

}

}

TA的精华主题

TA的得分主题

 楼主| 发表于 2010-5-6 09:13 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本章介绍了字符类、通用数量符、锚位符、记忆的小括号、反向引用及优先级等重要内容,前面的内容好懂、易记,后面的“记忆的小括号、反向引用和优先级”的内容需要重点理解与掌握,有一定难度。


1.字符类

字符类(character class),即在一对中括号([])中列出的所有字符,可以匹配类中的任何单个字符,它只匹配一个字符,但该字符必须在表中。譬如[abcdwxyz]或[a-dw-z](可用短横-指定一个字符范围,上面两个字符类是等价的)。

可以用双引号字符串中类似的字符快捷方式来定义一个字符类,譬如[000-177]匹配任何7比特ASCII字符。

在字符类前加一个脱字符(^)可以反置它,即只匹配不包含在中括号中的任何单个字符。譬如[^abc]匹配除了a、b和c之外的任何字符。注意,脱字符必须出现在中括号内字符的最前面,否则不具备反置的含义。如[a^bc]表示匹配a、^、b和c中的任一字符。


字符类的快捷方式:

d:匹配所有数字的字符类,等价于[0-9];d是digital的缩写

w:匹配所谓的“单词”字符,即普通字母、数字和下划线,等价于[A-Za-z0-9_];w是word的缩写

s:匹配空白,包括换页符、制表符、换行符、回车符和空个字符,等价于[ftnr ];s是space的缩写

D:匹配所有非数字字符类,即d的反置形式,等价于[^d];

W:匹配所有的非“单词”字符,即w的反置形式,等价于[^w];

S:匹配所有的非空白字符,即s的反置形式,等价于[^s];


2.通用数量符

使用大括号({})中的一对由逗号隔开的数字来指定重复的最少和最多次数。

/a{N,M}/:匹配重复N到M次的字符a;

/a{N,}/:匹配重复次数大于等于N的字符a,没有上限;

/a{N}/:匹配重复次数等于N的字符a,精确匹配;


3.锚位符(anchor)

^:标志字符串的头,可以理解为标志行首,譬如/^fred/匹配以fred开头的行;

$:标志字符串的尾,可以理解为标志行尾,譬如/fred$/匹配以fred结束的行;

b:单词边界锚位符,标志单词的开始与结束,用于精确匹配单词(单词中只含有w类型的字符),譬如/bfredb/精确匹配单词fred;

B:非单词边界锚位符,可以看作b的反置形式;


4.记忆的小括号及反向引用

小括号的一个功能是把模式的一些部分组合起来,它的第二个作用是要求正则表达式引擎记住与小括号中的模式匹配的那部分子串。也就是说,它不是记住模式本身,而要记住相应的部分字符串。在用小括号进行分组时,它们自动具有记忆功能。

反向引用(backreference)就是回头引用当前模式处理过程中保存的记忆。反向引用由一个反斜杠来构成,譬如,1包含第一个正则表达式记忆(即被第一对小括号匹配的字符串部分)。

反向引用被用来匹配与模式在前面匹配的字符串完全一样的字符串,譬如/(.)1/匹配任何字符,后跟同一个字符,即匹配任何双字符(如aa,11,两个连续空格等)。

反向引用使用n来标记第n个正则表达式记忆,确定n的方法是:从左到右,只数左括号的个数即可。譬如,在模式/((fredwilma)(stone))/中,1表示最外层的小括号匹配的字符串部分,2表示(fredwilma)小括号匹配的字符串,3表示(stone)小括号匹配的字符串。

在使用八进制转义字符时,如果小于100,则最高位写0,如012,以避免被误当作反向引用。


5.优先级

在介绍优先级之前,需要了解所谓的原子(atom),它是构成模式最基本的片段,可以看作不可分割的一个最小单元。原子包括独立的字符、字符类和反向引用。

正则表达式的优先级分四个级别,优先级数字越低,级别越高:

1.小括号,用作分组和记忆。小括号中的任何东西比其它东西都更紧密地“粘在一起”;

2.数量符,包括星号(*)、加号(+)、问号(?)和大括号构成的数量符;

3.锚位符和字符串序列,即一个单词中的字母粘在一起的紧密程度与锚位符粘着字母的紧密程度一样;

4.最低的优先级是表示选择的竖线。

TA的精华主题

TA的得分主题

 楼主| 发表于 2010-5-6 09:14 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本章介绍如何在Perl中使用正则表达式,介绍了“查找”(m//)、“替换”(s///)及split操作符、join函数的用法。


1.使用m//进行匹配

前面两章介绍的模式,都是在一对斜杠中的,如/fred/。但这实际上是m//(模式匹配)操作符的一个快捷方式,只所以说是快捷方式是因为可以选择任何定界符对把内容括住,而当选择了斜杠作为定界符时,就可以省略开始的m。譬如,m#fred#和/fred/是等价的。


有几个选项修饰符字母,也可称为标志符(flag),可以把它们附加在正则表达式的结束定界符后面,以改变表达式的缺省行为。

/i:进行不区分大小写的匹配,如/fred/i;

/s:使点号(.)可以进行任何字符的匹配,点号原先不能匹配换行符,加上这个标志符后,就可以匹配任何字符,如/fred.*lee/s;

可以组合使用标志符,组合的顺序不重要,譬如/fred/is和/fred/si是等价的。


2.绑定操作符=~

与$_匹配只是个缺省操作。绑定操作符(binding operator)=~告诉Perl用右侧的模式匹配左侧的字符串,而不是匹配$_。譬如:

if ($some_other =~ /brub/) {

...

}


3.在模式中替换

这里的替换指的是双引号替换,即在正则表达式中,可以把变量替换为它实际的值。进行变量替换时,需要将变量放在小括号中。譬如:

my $what = "larry";

if (/^($what)/) {

...

}


4.匹配变量和记忆的持久性

在正则表达式中使用\n对匹配的字符串进行反向引用,而在Perl中,使用$n来引用匹配的字符串。两者的区别是,\n回指当前正在进行匹配的正则表达式的第n个记忆,$n表示一个已经完成的模式匹配的第n个记忆。两者有个时间差,即在同一时刻指的并不是同一个字符串。譬如:

$_ = "Hello there, neighbor";

if (/\s(\w+),/) { # 记住空格和逗号之间的单词

print "the word was $1\n"; # $1 = Hello there

}

匹配变量一般保留到下一次模式匹配成功,即一个不成功的匹配会维持以前记忆的原状,但一个成功的匹配则全部重新设置它们。这是模式匹配一般总是在if或while的条件表达式中的一个原因。由于记忆不会永远保持,所以一般在模式匹配的后面马上使用这个记忆的变量,或者将这个记忆的变量拷贝到一个普通变量中,以便后面继续使用。譬如:

if ($wilma =~ /(\w+)/) {

my $wilma_word = $1;

...

}


在Perl中,有三个系统定义的模式匹配变量,即你无须自己定义这些变量即可使用它们:

$`:保存正则表达式引擎在找到匹配之前需要跳过的部分;

$&:保存实际与模式匹配的那部分字符串;

$':保存模式没有到达的字符串的剩余部分;

将这三个字符串按顺序连在一起,你总会得到原字符串:$`$&$'。


5.用s///进行替换

使用s///可以用一个替换字符串来替换一个变量匹配模式的部分,譬如:

$_ = "He's out bowling with Barney tonight.";

s/Barney/Fred/; # 用Fred替换Barney

s///有一个返回值,如果替换成功,则返回真;否则,返回假。

和m//类似,s///可以使用绑定操作符=~ 改变匹配的变量,譬如:

$file_name =~ s/Barney/Fred/; #在$file_name中查找Barney并将其替换为Fred

和m//类似,s///也可以使用不同的定界符,此处不再赘述。

和m//类似,s///使用一组标志符来改变缺省行为:

/g:进行全局替换,如果没有这个标志,则s///仅替换匹配的第一个模式;

/i,/s:用法和m//中的类似,此处不再赘述;


6.大小写转换

在替换的时候,可能经常希望替换字符采用了合适的大写(或小写,依需要而定)。这很容易用Perl来完成,即通过一些反斜杠转义。

\U转义符强制后面的字符都用大写,譬如:

$_ = "I saw Barney with Fred";

s/(fredbarney)/\U$1/gi; #$_现在是"I saw BARNEY with FRED."

\L转义符强制后面的字符都用小写;

缺省情况下,U和L会影响其后的所有(替换)字符串,除非使用\E关闭大小写转换,譬如:

$_ = "I saw Barney with Fred";

s/(\w+) with (\w+)/\U$2\E with $1/i; # $_现在是"I saw FRED with Barney."

当写成小写的形式时(\l和\u),它们只影响下一个字符,譬如:

$_ = "I saw barney with fred";

s/(fredbarney)/\u$1/gi; # $_现在是"I saw Barney with fred."

\u\L(或\L\u)表示全部小写,但是第一个字符大写;


7.split操作符

split操作符把一个字符串按照分割子(separator)分开。格式如下:

@result = split /separator/, $string;

split操作符在字符串中用模式/separator/扫一遍,返回一个由分割子分割的字段(子字符串)的列表。每当模式匹配时,就是一个字段的结束和下一个字段的开始,因此,任何可以匹配模式的东西都不会出现在返回的字段中。譬如:

@result = split /:/, "abc:def:g:h"; # @result = ("abc", "def", "g","h")


8.join函数

join函数完成split操作符相反的功能:split把一个字符串分成若干片段,而join则把一组片段粘合起来形成一个字符串。格式如下:

my $result = join $glue, @pieces;

join的第一个参数是粘合串,它可以是任何字符串。另一个参数是由片段组成的一个列表,join把粘合字符串放在片段之间。譬如:

my $x = join ":", 4,6,8,10,12; # $x = "4:6:8:10:12"

TA的精华主题

TA的得分主题

 楼主| 发表于 2010-5-6 09:26 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

正则举例

Sub perl()

Set x = CreateObject("scriptcontrol")
x.Language = "perlscript"
x.eval "$_ = qq(yabba dabba doo);if(~/(abba)/) {$a=$1;}"


MsgBox x.eval("$a")
End Sub

TA的精华主题

TA的得分主题

发表于 2010-5-6 11:28 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2010-5-6 12:43 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
如果赋值数组左边的列表只包含变量名,那么该列表可以用来对其元素进行初始化。请
看下面这个例子:
($a, $b, $c)=qw (apples oranges bananas);
在这个例子中, $ a被初始化为‘ a p p l e ,s ’$ b被初始化为‘ o r a n g e, s ’而$ c则被初始化为
‘ b a n a n a。 s 如’ 果左边的列表包含一个数组,那么该数组就接受来自右边列表的剩余值。现在
请看下面的例子:
在这个例子中, $ a被设置为‘p e a c h e s’。右边列表中的其余水果被赋予左边的@ f r u i t。$ c
没有留下任何元素来接受一个值(因为赋值语句左边的数组吸收了来自右边的所有剩余值),
因此$ c被设置为u n d e f。
另一个值得注意的问题是:如果左边包含的变量比它拥有的元素多,那么多余的变量将
接受u n d e f这个值。如果右边的变量比左边的元素少,那么右边多余的元素将被忽略。下面让
我们观察一个代码,以便理解这个概念:


Sub perl()

Set x = CreateObject("scriptcontrol")
x.Language = "perlscript"
x.eval "($a, $b, $c)=qw (apples oranges bananas);"


Debug.Print x.eval("$a"), x.eval("$b"), x.eval("$c"),



End Sub
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-12-22 18:13 , Processed in 0.036227 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表