#!/usr/bin/perl -w
print "\n----------------------Perl Regular Expression----------------------\n";
print "\n----------------------Perl Regular Expression Demo1----------------\n";
#下面例子正在匹配HTML<A>或<IMG>标记和对应的结束标记</A>或</IMG>之间的所有文本;
$text="<A>Here is an anchor.</A>";
if($text=~ /<IMG|A>/i){
print "Found an image or anchor tag."."\n";
}
#6.1使用正则表达式
#6.1.1使用正则表达式时,需要使用两个字符串处理运算符:模式匹配运算符m//和替换运算符s///。
# 转换运算符:tr///


#--------------------------------------------------------m//运算符---------------------------------------------------------------------
#6.1.1.1 m//运算符
# 默认情况下,m//运算符尝试匹配指定的模式和$_中的文本。
# 例如:在用户输入的文本中查找字符串exit(第二个反斜线之后的i修饰符是的模式匹配不区分大小写)。如果在$_中找到exit,则m//返回真;
# print "\n---------------------------(m//) Demo------------------------\n";
# print "Enter:";
# while(<>){
# if(m/exit/i){exit;}
# }

#=~:运算符指定m//运算符查找的字符串。在这里,指定运算符应该查找标量$line,而不是$_。这段代码没有改变$line的值:
# print "\n---------------------------(m//) and(=~) Demo------------------------\n";
# print "Enter:";
# while($line=<>){
# if($line=~m/exit/i){exit;}
# }

#!~:运算符对=~的返回值取反。
# print "\n---------------------------(m//) and(=~) (!) Demo------------------------\n";
# print "Enter:";
# while($line=<>){
# if(!($line=~m/exit/i)){exit;}
# }

#m//运算符使用频繁,可以忽略掉m部分,多数程序使用如下快捷方式:
# print "\n---------------------------(m//) and(=~) (!) Demo------------------------\n";
# print "Enter:";
# while($line=<>){
# if($line=~/exit/i){exit;}
# }

#与其他perl运算符一样,如果你不喜欢斜线,可以使用自己的定界符,在这种情况下必须使用m;
# print "\n---------------------------User Defined Limite Notation------------------------\n";
# print "Enter:";
# while($line=<>){
# if($line=~ m{exit}i){exit;}
# }

#PS:在标量上下文中,m//返回真或者假;在表的上下文中,如果使用“g”修饰符来进行全局查找,则m//返回所有匹配值的列表。
#例如,创建一个数组@a,它将容纳$_中的所有小写单词;
print "\n-----Use 'g ' to find list match value------\n";
$_="Here is the text";
@a=m/\b[^A-Z]+\b/g;
print "@a";
print "\n-----END------\n";
#对上面子程序解析如下:
#\b:匹配单词范围
#[^A-Z]:匹配除了大写字母以外的任何字符;
#+:确保可以找到多个匹配值;
#g修饰符:说明是全局查找,全局查找可以查找所有连续的匹配值。
#---------------------------------------------------------------------------------------------------------------------------

#----------------------------------------------------s///运算符--------------------------------------------------------------
#6.1.1.2 s///运算符
# s///运算符可以用一个字符串替换另一个字符串。
# 例如:用字符串old替换了字符串young
print "\n--------------------------(s///) USED-----------------------------\n";
$text_young="Pretty young.";
print "$text_young\n";
$text_young=~ s/young/old/;
print "$text_young\n";
print "\n------------------------END (s///) USED---------------------------\n";

#PS:m//和s///是从左边开始匹配。
#-------------------------------------------------------------------------------------------------------------------------------

#----------------------------------------------------tr///运算符--------------------------------------------------------------
$text= "His name is Tom.";
$text=~tr/o/j/;
print $text ."\n";
print "\n------------------------END (tr///) USED---------------------------\n";
#-----------------------------------------------------------------------------------------------------------------------------

#正则表达式:\b([A-Za-z]+)\b在文本字符串中匹配单词:
print "\n--------------------------(\b([A-Za-z]+)\b) USED-----------------------------\n";
$text="Pretty young.";
print "$text_young\n";
$text=~ /\b([A-Za-z]+)\b/;
print "$1\n";
print "\n------------------------END (\b([A-Za-z]+)\b) USED---------------------------\n";
#例子解析:
#表达式(\b([A-Za-z]+)\b)包含分组元字符、\b边界元字符和字符类[A-Za-z](匹配所有的大写和小写字母)和量词+,它指定在已指定的字符类中查找一个或多个字符。
#perl记住一个匹配,前面的代码称之为$1,并打印字符串中的第一个单词。

#在正则表达式中,任何单个字符都与自身匹配,除非它是具有特殊含义的元字符(例如$和^)
# print "\n--------------------------('$ and ^') USED-----------------------------\n";
# while(<>){
# if(m/^exit$/i){
# {exit;}
# }}
# print "\n------------------------END ('$ and ^') USED---------------------------\n";

#perl中特殊字符:
# \077-------------8进制字符
# \a-------------报警(铃声)
# \c[-------------控制字符
# \D-------------匹配非数字字符
# \d-------------匹配数字字符
# \E-------------启用模式元字符
# \e-------------转义
# \f-------------换页
# \L-------------小写,直至遇到\E
# \l-------------小写下一个字符
# \n-------------换行
# \Q-------------引用(禁止)模式元字符,直至遇到\E
# \r-------------回车
# \S-------------匹配非空白字符
# \s-------------匹配空白字符
# \t-------------制表位
# \U-------------大写,直至遇到\E
# \u-------------大写下一个字符
# \W-------------匹配非单词字符
# \w-------------匹配一个单词字符(字母数字字符和“_”)
# \xl-------------16进制字符

#PS:\w仅匹配一个字母数字字符,而不是单词,为了匹配单词,需要这样使用\w+(匹配一个或多个):
print "\n--------------------------(\w+) USED-----------------------------\n";
$text="Pretty young.";
print "$text_young\n";
$text=~ s/\w+/There/;
print "$text\n";
print "\n------------------------END (\w+) USED---------------------------\n";

#匹配任何字符:‘.’。这个字符可以匹配任意字符,但换行符除外(但是如果与m//和s///一起使用s字符修饰符,句点字符和换行匹配)
#用*替换字符串中的所有字符,g修饰符可以使替换操作在全局范围内进行。
print "\n--------------------------(.) USED-----------------------------\n";
$text="Pretty young.";
print "$text\n";
$text=~ s/./*/g;
print "$text\n";
print "\n------------------------END (.) USED---------------------------\n";

#诸如句点这样的字符在正则表达式中称为元字符(元字符包括:\|()[{^$*+?.),仅需在它们前面加入反斜线,就可以确保按照字面意义解释,而不是作为元字符解释。
#‘^’:匹配行首,让用户知道不应该用句点开始的句子。
print "\n--------------------------(^) USED-----------------------------\n";
$text=".Pretty young.";
print "$text\n";
if($text=~ m/^\./){
print "Should't start a sentence with a period!";
}
print "\n------------------------END (^) USED---------------------------\n";

#从C代码中删除注释,方法是通过使用*量词和.来代表任意数量的类似字符,以匹配定界符/*和*/之间的所有字符。
print "\n--------------------------(* and .) USED-----------------------------\n";
$text="count++;/* Increment count*/";
$text=~s/\/\*.*\*\///g;
#或者使用
#$text=~s|\/\*.*\*\/||g;
print $text;
print "\n------------------------END (* and .) USED---------------------------\n";

#可以使用多个字符组成字符类,而那个类将匹配其中的任意字符。字符类要包含在[字符类]中。也可以使用-字符指定字符范围
print "\n--------------------------([zi fu yuan zu ]) USED-----------------------------\n";
$text="count++;/* Increment count*/";
if($text=~/[couIite]/){
print "Yep,we got vowels.\n";
}
print "\n------------------------END ([zi fu yuan zu ]) USED---------------------------\n";

#如果使用^作为字符类中的第一个字符,则那个字符类将匹配其中没有的任何字符,在下面的例子,仅匹配了既不是字母也不是空白的字符:
print "\n--------------------------([^A-Za-z\s]+) USED-----------------------------\n";
$text="count 200 Increment 000 count ";
$text=~s/[^A-Za-z\s]+/521/;
print $text;
print "\n------------------------END ([^A-Za-z\s]+) USED---------------------------\n";

#提取$_中的全部小写的单词,并将它们存储在新数组@a中:
print "\n--------------------------(\b[^A-Z]+\b) USED-----------------------------\n";
$_="Here is the text";
@a=~m/\b[^A-Z]+\b/g;
print @a;
print "\n--------------------------end (\b[^A-Z]+\b) USED-----------------------------\n";

#PS:使用\b匹配单词边界
#通过将特定字符或者字符序列作为正则表达式中的文字或者字符类,就可以匹配特定字符或者字符序列。
#多重匹配模式:可以为模式指定一系列的选项,并用|分开个选项。例如,可以这样检查用户输入是否为"exit","quit","stop"
# print "\n--------------------------(|) USED-----------------------------\n";
# print "Enter exit|quit|stop:";
# while(<>){
# if(m/exit|quit|stop/){exit;}
# }
# print "\n--------------------------END (|) USED--------------------------\n";

# print "\n--------------------------(|) USED-----------------------------\n";
# print "Enter exit|quit|stop:";
# while(<>){
# if(m/^(exit|quit|stop)$/){exit;}
# }
# print "\n--------------------------END (|) USED--------------------------\n";
#PS:--------------------------------------------------------------------------------------------
#perl中的量词:
# *-----------------匹配0或多次
# +-----------------匹配1或多次
# ?-----------------匹配0或1次
# {n}-----------------匹配n次
# {n,}-----------------匹配至少n次
# {n,m}-----------------匹配至少n次,至多匹配m次
#-----------------------------------------------------------------------------------------------
#perl中的合法断言:
# ^-----------------匹配行首
# +-----------------匹配行尾(或者末尾前的新行)
# \A-----------------仅匹配字符串开头
# \B-----------------匹配非单词边界
# \b-----------------匹配单词边界
# \G-----------------仅匹配前一个m//g剩余的内容(仅仅能和/g一起使用)
# \Z-----------------仅仅匹配字符串的末尾,或者末尾前的新行
# \z-----------------仅仅匹配字符串的末尾
# (?=EXPR)-----------如果EXPR可以匹配下一个,则进行匹配
# (?!EXPR)-----------如果EXPR不能匹配下一个,则进行匹配
# (?<=EXPR)----------如果EXPR可以匹配前一个,则进行匹配
# (?<!EXPR)----------如果EXPR不能匹配前一个,则进行匹配
#--------------------------------------------------------------------------------------------------
#确保用户输入的所有行至少具有20个字符:
# print "\n--------------------------(.{20,}) USED-----------------------------\n";
# print "Enter:";
# while(<>){
# if(!m/.{20,}/){
# print "Please type longer line!";
# }
# }
# print "\n--------------------------END (.{20,}) USED--------------------------\n";

#默认情况下,量词非常贪婪的,这意味着通过创建从当前查找位置开始的合法匹配,它门将返回找到最长的匹配值。
#创建正则表达式:引用前一次匹配的向后引用
#在相同的表达式中引用前面的匹配:通过反斜线以及数字\1,\2,\3等,来引用相同模式中以前的匹配值。表达式\1代表第一次匹配,\2代表第二次匹配,依次类推。
#例如,处理html,并需要确保正在匹配从开始到相应的结束表姐之间的文本,如<A>到<\A>:
# print "\n--------------------------('\1') USED-----------------------------\n";
# $text="<A>Here is an anchor.<\A>";
# if($text=~/<(IMG|A)>[\w\s\.]+<\/\1>/i){
# print "Found an image or anchor tag.";
# }
# print "\n--------------------------END ('\1') USED--------------------------\n";

#在数字的前面加入$($1,$2,$3等)而在括号内引用模式之外的匹配。
#使用向后引用$1而将单词转换为缩写形式:
# print "\n--------------------------($1) USED-----------------------------\n";
# $text="<A>Here is an anchor.<\A>";
# if($text=~/<(IMG|A)>[\w\s\.]+<\/\1>/i){
# print "Found an image or anchor tag.";
# }
# print "\n--------------------------END ($1) USED--------------------------\n";

#Perl的特殊变量$&(引用前一个匹配),$'(引用前一次匹配之后的字符串),$`(引用前一次匹配之前的字符串)。$+引用括号内的最后一次模式匹配

#正则表达式扩展:
#(?#text)---------------------------------------指出是注释。将忽略这个表达式内的文本。
#(?;pattern)或者(?imsx-imsx:pattern)------------用(和)对子表达式分组,而不是向后引用。
#(?=EXPR)---------------------------------------正预测断言。如果EXPR可以匹配下一个,则进行匹配。
#(?!EXPR)---------------------------------------负向后断言,如果EXPR可以匹配上一个,则进行匹配。
#(?<=EXPR)--------------------------------------正向后断言,如果EXPR恰好匹配前一个,则进行匹配。
#(?<!EXPR)--------------------------------------负向后断言,如果EXPR不能匹配前一个,则进行匹配。
#(?{code})--------------------------------------计算Perl代码0的宽度断言。仅在使用use re ‘eval’ pragma 时才匹配。
#(?gtpattern)-----------------------------------匹配子字符串,如果定位在给定的位置,也将匹配这个子字符串。
#(?(condition)yes-pattern|no-pattern)或(?(condition)yes-pattern)------------指定条件表达式。
#(?ismsx-imsx)----------------------------------指定一个或者多个嵌入的模式匹配修饰符。
#------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------Deno--------------------------------------------------
print "\n------------------('$1' '$2' $3 and (?#text)') USED----------------\n";
$text="I see you";
$text=~ s/^(?# 1st)(\w+) *(?# 2nd)(\w+) *(?# 3rd)(\w+)/$3 $2 $1/;
print $text;
print "\n-----------------END ('$1 $2 $3 and (?#text)') USED-------------------\n";

#预测断言:(?=...)和(?!...)
#回想断言:(?<=EXPR)和(?<!EXPR)
#断言不是匹配本身的组成部分。
#----------------------------------------------------Demo----------------------------------------------------------
print "\n------------------------(?=EXPR) USED-----------------------------\n";
$_="I am going to Paris,London,and Vienna.";
print "Found all three ."if/(?=.*Vienna)(?=.*Paris)(?=.*London)/;
print "\n----------------------(?=EXPR) END-------------------------------\n";
#----------------------------------------------------Demo----------------------------------------------------------

# print "\n------------------------(m/^(exit|quit|stop)$/) USED-----------------------------\n";
# while(<>){
# if(m/^(exit|quit|stop)$/){
# print "You typed:$1\n";
# exit;
# }else{
# print "Nothing stored.\n";
# }
# }
# print "\n----------------------(m/^(exit|quit|stop)$/) END-------------------------------\n";

#----------------------------------------------------Demo----------------------------------------------------------
# print "\n------------------------(m/^(?:exit|quit|stop)/) USED-----------------------------\n";
# while(<>){
# if(m/^(?:exit|quit|stop)$/){
# if($1){
# print "You typed: $1\n";
# exit;
# }else{
# print "Nothing stored.\n";
# }
# }
# }
# print "\n----------------------(m/^(exit|quit|stop)/) END-------------------------------\n";

#ps:与m//和s///一起使用修饰符
#e--------------------------------指出s///的右边是要计算的代码
#ee-------------------------------指出s///的右边要计算的字符窜并作为代码运行,然后再次计算它的返回值
#g--------------------------------在全局范围内执行所有可能的操作
#gc-------------------------------在匹配失败之后,不要重复查找位置
#i--------------------------------忽略字母大小写
#m--------------------------------让^和$匹配嵌入的\n字母
#o--------------------------------仅对模式进行一次编译
#s--------------------------------让、字符匹配新行
#x--------------------------------忽略模式中的空白,并允许进行注释
#--------------------------------------------------Demo----------------------------------------------------------
print "\n---------------------use(m//g) start----------------------\n";
$text="Here is the texxxxxxxt";
while($text=~m/x/g){
print "Found another x.\n";
}
print "\n---------------------use(m//g) end----------------------\n";
#PS:每次在标量上下文中使用m//g时,它将记住上一次查找结束的位置,并从那个位置开始。
#--------------------------------------------------Demo----------------------------------------------------------
#查找由4个字母构成的单词
print "\n---------------------use(m/\w{4}\b/g) start----------------------\n";
@a=("Here is the test"=~m/\w{4}\b/g);
print @a;
print "\n---------------------use(m/\w{4}\b/g) end----------------------\n";
#--------------------------------------------------Demo----------------------------------------------------------
#用s///g将字符串中的所有匹配值替换:
print "\n---------------------use(s/./*/g) start----------------------\n";
$a="Here is the test";
$a=~s/./*/g;
print $a;
print "\n---------------------use(s/./*/g) end----------------------\n";

#用tr///转换字符串
#格式:tr/LIST/LIST/
# y/LIST/LIST/
#--------------------------------------------------Demo----------------------------------------------------------
#使用这个运算符进行文本替换,并用第2个列表中的相应字符来替换第一个列表中的所有字符。下面例子使用字母o替换字符串中的i:
print "\n---------------------use(tr/i/o/) start----------------------\n";
$a="Here is the test";
$a=~tr/i/o/;
print $a;
print "\n---------------------use(tr/i/o/) end----------------------\n";
#--------------------------------------------------Demo----------------------------------------------------------
#指定处理字符范围,下面例子将字符串转换为大写形式:
print "\n---------------------use(tr/a-z/A-Z/) start----------------------\n";
$a="Here is the test";
$a=~tr/a-z/A-Z/;
print $a;
print "\n---------------------use(tr/a-z/A-Z/) end----------------------\n";
#--------------------------------------------------Demo----------------------------------------------------------
#tr///运算符返回转换次数,下面例子:统计$_中字母x出现的次数,而不影响字符串:
print "\n---------------------use(tr/x/x/) start----------------------\n";
$text="Here is six xxxxxx";
$xcount=($text=~tr/x/x/);
print $xcount."\n";
print $text."\n";
print "\n---------------------use(tr/x/x/) end----------------------\n";

#和tr///一起使用修饰符:
#perl中可以和tr///一起使用:
# c------------------------对查找列表求补
# d-----------------------删除没有替换的字符
# s-----------------------删除重复的替换字符

#匹配单词:
#--------------------------------------------------Demo----------------------------------------------------------
#匹配单词:
print "\n---------------------use(/(\S+)/) start----------------------\n";
$text="Here is six xxxxxx";
$text=~ m/(\S+)/;
print $text;
print "\n---------------------use(/(\S+)/) end----------------------\n";
#--------------------------------------------------Demo----------------------------------------------------------
#匹配单词:\w匹配字母数字和下划线“_”
print "\n---------------------use(/(\w+)/) start----------------------\n";
$text="Here is six xxxxxx";
$text=~ m/(\w+)/;
print $text;
print "\n---------------------use(/(\w+)/) end----------------------\n";

 

                                                                      Perl正则表达式学习笔记_sed