正则表达式---重点

2020-04-04  本文已影响0人  oasis_m

声明:所有文章只作为学习笔记用,转载非原创

在线正则
 https://blog.csdn.net/shellching/article/details/76527720 

-------编程语言支持高级正则表达式 还是很有难度的
grep / sed awk 文本编辑器 IDE 都支持基础正则

分类:
基础正则  bre  basic regular expression 
扩展        ere   extended regular expression 
变成语言支持的正则

BRE和ERE语法基本一致 只有部分元字符需要区别对待

扩展正则中这些元字符可以直接使用 :  ?   、 + 、  {   、 } 、 | 、   ( 、 )

基础正则这些字符都需要加反斜线转义: \?   、 \+  、\{   、  \}  、   \|  、\( 、 \)   
提示:基础正则中这些符号加反斜线, 才能具有通配功能。不加的话就是普通字符

eascape \  转义:是引用单字符的方法.在单个字符前面的转义符(\ 倒斜杠)告诉shell不必特殊解释这个字符,只把它当成字面上的意思. 


 # echo '1234 helo world 学,U)&)^&[]' | grep  -E 'h?'
1234 helo world 学,U)&)^&[]
 # echo '1234 helo world 学,U)&)^&[]' | grep  'h?'
   echo '1234 helo world 学,U)&)^&[]' | grep  'h\?'
grep  sed 默认使用基础正则
grep -E  、 sed -r  、  egrep  、  awk 扩展正则

基本作用: 搜索文本
学习正则本质就是学习各种各样的元字符,并记住这些元字符的含义。
元字符: 预定义好的具有特殊含义的符号,这些符号能够进行通配。
可读性非常差

单引号”; 双引号””; 反向单引号引用强弱程度比较
 https://www.cnblogs.com/wkfvawl/p/9982442.html 

grep 正则
https://www.cnblogs.com/songgj/p/8906005.html
https://www.cnblogs.com/lovychen/p/7429682.html 

#语法
grep -E 'pattern'  filename
cmd | grep -E 'pattern'

#设置一些环境变量
echo $GREP_COLORS
grep --color=auto/always  -E xxx.txt
cat ~/.bashrc  配置环境变量就可以不用打命令的时候加选项了
exec $SHELL  #设置bashrc 生效 重新加载shell 相当于退出重登

#纯普通字符匹配,相当于精确匹配
  
echo "hello world"  | grep 'world' 
sycn
echo 3 >/proc/sys/vm/drop_caches

grep -E '4574' a.txt   #精确
grep -E '[1-9]{4}' a.txt # 非精确搜索

#基础正则元字符 

1 匹配字符:
 abc : 匹配字符串 "abc " ,普通字符的匹配
[abcde] : 匹配中括号内的任意单个字符
                a[xyz]b : 可以匹配 axb ayb 不能匹配 aab abb
              #根据示例 了解匹配过程  
               [root@master ~]# echo "hello world" | grep -E 'h[abcde]'
               hello world                      #只能匹配到he
               [root@master ~]# echo "hello worhd" | grep -E 'h[abcde]'
               hello worhd                     #可以匹配到he hd

1.1 中括号: 匹配的全是括号内的单个字符
x[abc]z : xaz xbz xcz
取反:
x[^abc]b : 只要不是中括号中的字符,都可以匹配
范围
[a-z] [^a-z]
[A-Z]
[0-9]
[0-59] : 表示匹配[0,1,2,3,4,5,9] 不是0到59
            echo "36" | grep -E '[0-59]'   #只能匹配到3
            echo "a8" | grep -E '[0-59]'   # 不能匹配到任何
[a-z0-9A-Z]
[A-z] [a-Z] :建议不要写这种横跨大小写范围的表达式,不同地方范围表达的含义不同

有些按照字典顺序排序时候,
[a-d] : 不等价于abcd ,而是aBbCcDd 
           如果想要等价于abcd 需要locale 环境设置为C
           LC_ALL=C
            https://www.cnblogs.com/wajika/p/6592659.html 
 https://blog.csdn.net/z4213489/article/details/7937894 

 LC_ALL
它是一个宏,如果该值设置了,则该值会覆盖所有LC_*的设置值。注意,LANG的值不受该宏影响。
"C"是系统默认的locale,"POSIX"是"C"的别名。所以当我们新安装完一个系统时,默认的locale就是C或POSIX。
locale 包括(Language), 地域 (Territory) 和字符集(Codeset)
zh_CN.UTF-8,zh代表中文,CN代表大陆地区,UTF-8表示字符集
locale的书写格式为: 语言[_地域[.字符集]]
LC_ALL和LANG优先级的关系: LC_ALL > LC_* >LANG 

#中括号如何匹配: 
^  脱字符 :开头或结尾
 -  范围  : 开头或结尾
 ]  闭括号 :必须放在开头 []^] 、 [-^] 、[]-] 、[]^-]
提示:匹配上面2个或三个
如何在中括号匹配这两个字符
echo 'abcd-def' | grep '[-abcd]'  #放在开头
echo 'abcd-d^ef' | grep '[^abcd^efda]'


正则表达式 \w \s \d \b 用法:
. 匹配除换行符以外的任意字符
\n 匹配换行
\t  匹配制表符号
\w 匹配字母或数字或下划线 (a-zA-Z0-9_)
\W :匹配非单词字符  [^a-zA-Z0-9_]
\s 匹配任意的空白符
\d 匹配数字                      等价于[0-9]
\D 匹配非数字字符
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
. 表示任意单个字符
其中,[^A-Z]表示除了不包含大写字母,^取反;^[A-Z]表示以大写字母开头
提示: 有些程序并不支持上面的反斜线转义元字符,例如gnu grep2.6 不支持 \s \d  ,grep 2.20支持\s 不支持\d , sed 不支持\d 
单词: 在正则表达式中的含义,[^a-zA-Z0-9_]组成的字符或字符串都是单词 例如 nihao, hello world_ 第一个nihao 第二个hello  第三个world_ 
示例:
[root@master ~]# echo 'abc def 1234' | grep '\s'
abc def 1234
[root@master ~]# echo 'abc def 1234' | grep '\S'
abc def 1234
[root@master ~]# echo 'abc def 1234' | grep '\w'
abc def 1234
[root@master ~]# echo 'abc def 1234' | grep '\W'
abc def 1234
[root@master ~]# echo 'abc def 1234' | grep '\s\w'
abc def 1234
# . 点匹配任意单个字符
echo "abc def 1234" | grep '.'
echo "abc def 1234" | grep 'a.'
1.2 中括号之字符类 
posix 定义好的字符类,请自行查找
还有语言支持非posix 字符类
 [:lower:]  : 等价a-z
 [:alnum:]  :代表了0-9A-Za-z  等价  [:lower:]+ [:upper:] +
                    [:digit:] 
 使用时:
 [[:alpha:]]  : 任意字符
echo '1234 helo world 学,U)&)^&' | grep '[12[:alpha:]]

1.3 等价类和排序类 (只做了解)
[=x=] : 普通字符和带有重音字符(一到四声音)
[.xyz.] : 排序类 collating symbol 

#shell 中输入制表符
ctrl+v+tab 

2 位置匹配(锚定) 
只匹配位置,不匹配字符,不会消耗字符数量,也称为零宽断言
^ 匹配行首
$ 匹配行尾
\< 匹配单词开头位置
\> 匹配单词结尾位置
\b 匹配单词边界(开头和结尾 \bword\b 等价 \<word\>
\B 非单词边界
示例:
echo "abc def 1234" | grep '.\>'
echo "abc def 1234" | grep '\b1234\b'
echo "abc def 1234" | grep '\B234'

#正则表达式的匹配过程,
------ 消耗字符和交换字符的问题!
----某轮匹配成功,消耗所有匹配成功字符
----某轮匹配失败,消耗本轮匹配的首字符,剩余字符被交还

每一论正则的匹配,都需要从正则的第一个元素从头开始匹配。
  # abc      "xaabcxyz"
     echo "aaaaa" | grep -o 'aa'   -o: 匹配过程

一轮匹配   
扫描第一个字符 ,和正则表达式的第一个元素进行匹配
如果匹配失败,这一轮正则匹配失败
二轮匹配  
扫描下一个字符,从头开始和正则表达式匹配
如果成功,则继续扫描下一个字符和正则的下一个元素匹配
如果这个字符匹配失败,同一
交换除了第二轮匹配开始的首字符外所有字符
交换知乎,从交换的第一个字符开始进入下一轮匹配
第三轮:
如果匹配成功,则不交换匹配成功的字符
然后从匹配成功的下一个字符进入下一轮匹配



3 量词(重复匹配次数) 贪婪匹配
基础正则表达式中,对于量词的元字符需要加上反斜线转义
结论: 量词它是正则表达式中的隐含修饰符,它修饰的是前面一个字符或前面一个子表达式,它自身不是正则表达式中的独立元素,量词和它所修饰的字符或子表达式组合起来才是正则表达式中的独立元素。

{m} 表示匹配前一个字符或前一个子表达式m 次
{m,n} 最少m次,最多n次
{m,}   至少m次
{,n}  最多n次  :有些语言不支持(perl 不支持)
         注意: 匹配0次也成功,只不过匹配的是空字符,但是grep 没法显示
? :0或1次 等价{0,1} {,1}
*  :0或多次  等价于{0,}  
    提示: .* 匹配任意字符、任意长度
                    而不是某个字符任意长度
                    星号是量词
      ".*" : 3 3333 33333 abcdef (也能匹配) 
+ :1或多次   等价于 {1,}


示例: 
a{3} 匹配a 三次

#echo "aaaaa" | grep -E 'a{3}'
aaaaa
# echo "abc" | grep -E '[abc]{3}'

 [root@master ~]# echo "hello world" | grep -Eo '[a-z]{,4}'
hell
o
worl
d
[root@master ~]# echo "hello world" | sed -r 's/[0-9]{,4}/_/g'
_h_e_l_l_o_ _w_o_r_l_d_
#和上一条对比,理解匹配的过程
  匹配0次的也是有过程的

思考:量词会出现大量的回溯,是正则表达式的性能杀手
echo "world2222222222" | grep -Eo '[0-9]{100}'
提示:匹配了55次,性能问题 : 回溯(回头匹配)
           如果有99个2呢 4950次回书

[root@master ~]# echo "abcdef" | grep -E 'a[b-f]*f'
abcdef
提示 :a 第一个元素  [b-f]* 是第二个元素 f 第三个元素
            f 在第二个元素中匹配中交回,匹配了最后一个

[root@master ~]# echo "abcdef" | grep -E 'a[b-c]*f' 无匹配的
 提示: 这个* 是和[] 中算一个整体

#实现非贪婪匹配
基础正则和扩展正则都只支持贪婪匹配,不支持非贪婪匹配
示例:
[root@master ~]# grep '^m.*:' /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/false
mysftp:x:1006:1006::/data/sftp/mysftp:/bin/false
#非贪婪
perl -nE 'say $& if /^m.*?:/' /etc/passwd

[root@master ~]# grep '^m[^:]*:' /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/false
mysftp:x:1006:1006::/data/sftp/mysftp:/bin/false
上一篇下一篇

猜你喜欢

热点阅读