个人学习策略
主用python.
看懂perl 和 tcl 即可。
之前的存货
开始搬砖后,整理 ”网络发布版笔记“ 的心思寡淡了好多,可能就是被工作榨干的原因8…
但今天至少得赶个1024节日… ( ̄▽ ̄)"~
是什么
Perl (Practical Extraction and Report Language),实用报表提取语言。
偏向文本处理的脚本语言。
脚本的作用
实现一些自动化工作:如写个tcl,由当前系统时间自动生成唯一的版本号;设计一个脚本进行数据格式转换;用脚本实现个人HDL编码习惯的module模板;
脚本语言是文本文件,解释执行。
安装
perl的编译器有 ActiveStatePerl 和 Strawberry Perl,前者轻量级,后者包含些第三方库CPAN,自己定,以下以后者为例;
下载语言包位置:Perl Download
检查系统环境变量path是否更新:
cmd中输入:perl -v ;
有显示则成功,否则自己加环境变量到path中:
把perl 安装地址 .\perl\bin 加到path环境变量里即可.
(重新验证得重开cmd)
各种脚本语言的对比:perl、tcl、python
大部分Linux都自带了这三种脚本语言。
正则表达式
三个都支持正则:但perl支持最好最简洁、py兼容Perl的标准但要re库、tcl用的是另一套标准。
Python
语言风格:类似matlab;
优势:写一些开发用个人的小工具,有更丰富、成熟的库而更有优势。
缺陷:EDA工具支持性不好;分为 2.7 和 3.x 俩不兼容的版本,有点麻烦;
后缀:.py
Tcl
语言风格:类似C库,被C调用很方便;
优势:EDA支持性好;
EDA工具内置的console都集成、支持 tcl,如:ModelSim、Vivado、Quartus;
故tcl能更好地拓展EDA工具的功能和使用。
缺陷:扩展库不够多而且老;
后缀:.tcl
Perl
语言风格:类似shell的拓展;
优势:深度集成正则,故很适合文本处理;优势之一是丰富的第三方库(CPAN)
缺陷:库的质量难以保证;对文本外的开发没啥优势;且py也支持perl的正则标准,够用了。
perl的缺陷是更偏向文本处理、库的稳定性也不够。
后缀:.pl 或 .plx
关键文本头
#!自己的perl目录/bin/perl -w -w表示开启warning.
不知道目录,linux下可用 which perl查;
Linux下的系统指令和Windows下不同,Windows下是dos指令;
运行
执行文件:
perl 文件名.pl
cmd中执行单行:
perl -e 语句
行尾要有分号 ;
不关心空白;
弱语言类型,类似makefile.
语句块的{} 不能省略,不像C的单句可省。
运算符同C,
多了个乘幂**;逻辑非用的是not;逻辑或、逻辑且,支持and/or也支持&& / ||;
支持 +=、++ 这类的使用;
定义
标量 用 $;后面正则元字符里还有符号$,勿混淆!
$,那自然是空(不是空格哈).数组 用 @
哈希 用 %
使用
使用都是用$!直接加符号即可,不用括号.
e.g. 定义和使用都是 $var ;别和makefile弄混了—— makefile使用需要有 {},perl不用.
数值的使用
默认把整数按浮点数存;
$a = 666;
$a = 666.66 + 6.6e+6 -0.66;
数组
#定义
@array = (1,2,3);
@str = ( "1", "2", "3");
#使用
print $str[0];
# 数组复制
@copy = @array;
# 获得数组个数
$len = @array; #取决于等号左边的变量类型
哈希
#定义
%data = ('key1' => 1, 'key2' => 2);
#使用
print $data{'key1'};
大小写敏感,同C. —— 字母、数字(不可开头)、下划线.
不会自动换行;用不用括号()都行
print(1..5); #输出 1 2 3 4 5
print "xxx"; # 单输出
$str="ABC";
print $str, "\n"; #同下
print "$str\n"; #同上,因为会自动转义
$num = 6.66;
print("牛哇牛蛙: ",$num, "\n" ); # 多段输出,其实有没有括号无所谓
print "牛哇牛蛙",$num, "\n"; # 也OK.
# Error print ($num + "\n"); # + 只能用于数值计算
单行
#
多行
=pod
...
=cut
\
大体使用是和 C 一致,多了一些内容:
\u #下个字符,强制大写
\l #下个字符,强制小写
\U #后续字符,全部强制大写,用\E结束
\L #后续字符,全部强制大写,用\E结束
\Q #后续非单词字符,强制转义,用\E结束
\E #上述连续行为的结束标志
可以跨行写内容(输出包含换行符,同原格式);
单引号
强制视为文本,不解析转义;
双引号
会对串内包裹内容 解析转义;
print "$name 666" #转义
print '$name 666' #不转义,且可多行内容
print "123
456" #包含换行符
print '123
456' #同上
混合使用,同python:不用转义,自动夹杂。
字符串的拼接
$a = "abc";
$b = "efg";
# 正确的串拼接方式 1
$c = "$a$b"; #别有空格
# 正确的串拼接方式 2
$c = $a.$b;
# 错误的串拼接方式
# $c = $a + $b; # + 号只能进行数值计算
# $c = ($a, $b); # 没毛用
存储大段原格式字符串文本
用 = << "标志" 来存文本,意思是:从下一行开始,俩 标志 之间夹杂的所有字符都按原格式存入变量中。
$str = << "EOF";
EOF
正所谓天下大事,合久必分,分久必合...
很久很久以前...
...
EOF
print $str; # 就是上面这段文本
vstring
用来表示IP这种用 . 隔开的数字;可用v开头即可:
$ip = v192.168.0.1;$
但我试了一下,乱码。( ̄▽ ̄)"
字符串比较
$a lt $b # 串a < 串b? 成立则1.
$a gt $b # 串a > 串b? 成立则1.
$a le $b # 串a <= 串b? 成立则1.
$a ge $b # 串a >= 串b? 成立则1.
$a eq $b # 串a == 串b? 成立则1.
$a ne $b # 串a != 串b? 成立则1.
$a cmp $b # 串a < 串b,则1;串a == 串b,则0;串a > 串b,则-1;
__FILE__ #当前perl脚本的 文件名
__PACKAGE__ #当前脚本的 包名
__LINE__ #当前 行号
支持 a= b?c:d;
同C.
if-elsif-else
是 elsif 不是 else if !
if() {}
elsif() {}
else {}
反人类的 unless
if是真,则执行;unless是假,则执行.
unless(A){} # A为false,才执行
elseif(B){} # 同if-else, B真,才执行
else{} #剩余的
switch
switch (){
case 1 { print "数字 1" }
case "a" { print "字符串 a" }
case [1..10,42] { print "数字在列表中" }
case (\@array) { print "数字在数组中" }
case /\w+/ { print "正则匹配模式" }
case qr/\w+/ { print "正则匹配模式" }
case (\%hash) { print "哈希" }
case (\&sub) { print "子进程" }
else { print "不匹配之前的条件" } #对标C的default
}
while / do-while
while() {
}
do{
} while()
until (和while反着来)
until( A ){ # A 为真,则不执行
}
for
for( ; ; ){
}
foreach
用于数组内的元素迭代.
foreach $a (@list) { #若元素$a 在list中,则执行
}
是常用语言中最强大的正则功能。
三种基本形式
m/.../(可简写为 //);s/...A.../...B.../; 把A换成B.tr/...A.../...B.../;与 =~ 与 !~ 组合使用:
=~:匹配.!~:不匹配.# 匹配 Example
$str = "I love studying...";
if( $str =~ /love/ ){ #单句也不能省略 {}
print "match";
}
elsif( $str !~ /love/ ){
print "not match";
}
# 替换 Example
$str = "I love studying...";
$str =~ s/love/hate/;
print "$str\n"; #输出 I hate studying...
# 转化 Example
$str = "I love studying...";
$str =~ tr/a-z/A-Z/; #小写字符换成大写
print "$str\n"; #输出 I HATE STUDYING...
分别可以后接不同的下操作符
i 忽略大小写;
m 多行模式;
s 单行匹配;
o 仅执行一次;
g 全局匹配;
s 产出重复字符;
其他,略了。
正则匹配后的内容提取
$` # 匹配部分的前一部分字符串
$& # 匹配成功的字符串
$' # 匹配剩余的字符串
$n # 表正则式中的 第n个小括号 匹配成功的串值,如$1, $2
通用的正则元字符与转义字符
类似vim,copy自vim章节:(maybe滞后)
^ #匹配字符串的“开头”;vim中则表行首;
$ #匹配字符串的“末尾”,不是换行符哈,是串尾;vim中则表行尾;
< #匹配单词首。
> #匹配单词尾。
\b #匹配一个单词的边界。
\d #匹配任意数字。
\D #匹配任意非数字字符。
x? #匹配一个可选的 x 字符 (i.e.匹配 1次或 0次)。
x* #匹配0次或者多次 x 字符。
x+ #匹配1次或者多次 x 字符。
x{n} #匹配n个 x字符
x{n,m} #匹配 x 字符,至少 n 次,至多 m 次。
(a|b|c) #要么匹配 a,要么匹配 b,要么匹配 c。
(x) #一般情况下表示一个记忆组 (remembered group)。你可以利用 re.search 函数返回对象的 groups() 函数获取它的值。
. #匹配任意单个字符,换行符\n不算
\s #匹配所有空白符,包括换行
\S #匹配所有非空白符
\w #匹配 字母|数字|下划线
\d\D #表示任意字符,包括换行符
\s\S #也表示任意字符,包括换行符
# 以下是几个转义符
\n #1个换行符
\r #1个回车符
\t #1个制表符
\f #1个换页符s
# 以下是判断逻辑,需要和 () 联用,
# 来截取特定情境下的串,如(?!a|b),不要字符a或字符b.
# e.g. 我需要截取 aaabbbccc 中的bbb,则正则表达式为:(?<=aaa).*(?=ccc)
?!pattern #需要后面 不跟pattern的
?!<pattern #需要前面 不跟pattern的
?=pattern #需要后面 跟pattern的
?<=pattern #需要前面 跟着pattern的
?i #后面字符忽略大小写
?-i #前面字符忽略大小写
明辨 变量定义的$ 与 正则元字符$
$tag = "stone";
$str = "$tag \$tag stone\nLine 2: stone";
$str =~ s/$str$/666/;
print #str, "\n"; # 问原串str,以及后输出是什么?
#str原串:
#stone $tag stone
#Line2: stone
#输出内容:
#stone $tag stone
#Line2: 666