免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2801 | 回复: 7
打印 上一主题 下一主题

请教高手:grep及正则表达式的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-10-09 21:03 |只看该作者 |倒序浏览
执行结果如下:
wxdlut@wx81:~/regex> grep '1+1=2' test1.txt      // 第一个
1+1=2
wxdlut@wx81:~/regex> grep '1\+1=2' test1.txt     // 第二个
123+111=234
wxdlut@wx81:~/regex> cat test1.txt
1+1=2
123+111=234
ABC
abc
for the wise
otherwise
wxdlut@wx81:~/regex>

1、根据如下帖子,七楼的回答(我也觉得正确)
http://bbs.chinaunix.net/thread-1232393-1-1.html
7楼 发表于 2008-08-04 10:20 | 只看该作者
--------------------------------------------------------------------------------


这个和grep本省没有关系,而是和shell有关系,
比如:

grep "\\" file 这个为什么会失败呢?
因为用双引号,shell先把\\转义,就成了\,grep接收到的只有\,\是特殊字符,后面应该跟需要转义的字符,所以只有一个\就出错了。

如果用双引号,查找一个\,就应该用四个\:
grep "\\\\" file 这样就对了,这样等同于:
grep '\\' file

第一条命令shell把四个\,转义成2个\传递给grep,grep再把2个\转义成一个\查找
第二条命令shell没转义,直接把2个\传递给grep,grep再把2个\转义成一个\查找
其实grep执行的是相同的命令。

2、根据《深入浅出之正则表达式(一)》中的
http://blog.chinaunix.net/space. ... log&cuid=425967
    特殊字符

对于文字字符,有11个字符被保留作特殊用途。他们是:

[ ] \ ^ $ . | ? * + ( )

这些特殊字符也被称作元字符。

如果你想在正则表达式中将这些字符用作文本字符,你需要用反斜杠“\”对其进行换码 (escape)。例如你想匹配“1+1=2”,正确的表达式为<<1\+1=2>>.
需要注意的是,<<1+1=2>>也是有效的正则表达式。但它不会匹配“1+1=2”,而会匹配“123+111=234”中的“111=2”。因为“+”在这里表示特殊含义(重复1次到多次)。

根据以上两点,grep '1+1=2' test1.txt, shell直接把1+1=2传递给grep,grep再根据1+1=2查找,但根据“2、根据《深入浅出之正则表达式(一)》中的”的解释,此时应该匹配123+111=234才对啊?
grep '1\+1=2' test1.txt的结果不理解?


请高手帮忙解答一下,十分感谢!

论坛徽章:
0
2 [报告]
发表于 2011-10-09 22:25 |只看该作者
本帖最后由 j3kljs02398j 于 2011-10-09 22:36 编辑

回复 1# wxdlut

info grep
   
3.6 Basic vs Extended Regular Expressions
In basic regular expressions the meta-characters `?', `+', `{', `|',
`(', and `)' lose their special meaning; instead use the backslashed
versions `\?', `\+', `\{', `\|', `\(', and `\)'.

grep 默认的时候元字符+要用元字符序列\+来表示,如果直接写成+,那么会和普通字符一样。
grep '1+1=2' test1.txt
这里+直接当普通字符了,所以匹配包含1+1=2的行
grep '1\+1=2'
grep把"\+"当成元字符(至少匹配一次),所以匹配了123+111=234

如果启用了-E option,那么就不用这么麻烦了,+直接解释成元字符。结果正好和前面相反,你可以试试。
遇到困难,多用info!

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:51:162015年亚洲杯之阿曼
日期:2015-04-07 20:00:59
3 [报告]
发表于 2011-10-09 22:33 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
4 [报告]
发表于 2011-10-10 10:40 |只看该作者
回复 2# j3kljs02398j

恩 说的很对,“遇到困难,多用info!”多用man,多谢了!
本来对用grep来学习正则表达式很迷茫,现在知道了,加上-P,就可以利用perl的正则表达式规则

wxdlut@wx81:~/regex> grep '[A-Z][A-Z]*' test1.txt
ABC
abc
for the wise
otherwise
wxdlut@wx81:~/regex> grep -E '[A-Z][A-Z]*' test1.txt
ABC
abc
for the wise
otherwise
wxdlut@wx81:~/regex> grep -P '[A-Z][A-Z]*' test1.txt
ABC

-P, --perl-regexp
              Interpret PATTERN as a Perl regular expression.
-E, --extended-regexp
              Interpret PATTERN as an extended regular expression (see below).

In  other implementations, basic regular expressions are less powerful.  The following description applies to extended regular expressions; differ&acirc;

论坛徽章:
13
双鱼座
日期:2013-10-23 09:30:05数据库技术版块每日发帖之星
日期:2016-04-20 06:20:00程序设计版块每日发帖之星
日期:2016-03-09 06:20:002015亚冠之塔什干火车头
日期:2015-11-02 10:07:452015亚冠之德黑兰石油
日期:2015-08-30 10:07:07数据库技术版块每日发帖之星
日期:2015-08-28 06:20:00数据库技术版块每日发帖之星
日期:2015-08-05 06:20:002015年迎新春徽章
日期:2015-03-04 09:57:09辰龙
日期:2014-12-03 14:45:52酉鸡
日期:2014-07-23 09:46:23亥猪
日期:2014-03-13 08:46:22金牛座
日期:2014-02-11 09:36:21
5 [报告]
发表于 2011-10-10 16:35 |只看该作者
学习了

论坛徽章:
1
IT运维版块每日发帖之星
日期:2016-04-30 06:20:00
6 [报告]
发表于 2011-10-10 21:44 |只看该作者
grep '\\' file

第一条命令shell把四个\,转义成2个\传递给grep,grep再把2个\转义成一个\查找
第二条命令shell没转义,直接把2个\传递给grep,grep再把2个\转义成一个\查找
我觉得粗体部分解释是不对的,
[root@Centos5 ~]# echo '\\123'|grep '\\'
\\123
就是传递了2个\\给grep

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
7 [报告]
发表于 2011-10-10 21:59 |只看该作者
回复 6# 失落之岛

$ echo '\\123' | grep '\\'
\\123

$ echo '\1231\' | grep '\\'
\1231\

论坛徽章:
1
IT运维版块每日发帖之星
日期:2016-04-30 06:20:00
8 [报告]
发表于 2011-10-11 21:01 |只看该作者
回复  失落之岛

$ echo '\\123' | grep '\\'
\\123

$ echo '\1231\' | grep '\\'
\1231\
jason680 发表于 2011-10-10 21:59


看来还是我弄错了,这个真有点绕 先记下了。感谢了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP