免费注册 查看新帖 |

Chinaunix

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

正则表达进阶大讨论!欢迎参与讨论!(获奖名单已公布-2012-7-6) [复制链接]

论坛徽章:
49
15-16赛季CBA联赛之福建
日期:2016-06-22 16:22:002015年亚洲杯之中国
日期:2015-01-23 16:25:12丑牛
日期:2015-01-20 09:39:23未羊
日期:2015-01-14 23:55:57巳蛇
日期:2015-01-06 18:21:36双鱼座
日期:2015-01-02 22:04:33午马
日期:2014-11-25 09:58:35辰龙
日期:2014-11-18 10:40:07寅虎
日期:2014-11-13 22:47:15申猴
日期:2014-10-22 15:29:50摩羯座
日期:2014-08-27 10:49:43辰龙
日期:2014-08-21 10:47:58
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-05-31 16:34 |只看该作者 |正序浏览

获奖名单已公布,详情请看:http://bbs.chinaunix.net/thread-3757480-1-1.html

在计算机科学中,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或 替换那些符合某个模式的文本内容。许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则 表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。

随着互联网的迅速发展,几乎所有工具软件和程序语言都支持的正则表达式也变得越来越强大和易于使用。正则表达式在Perl、Java、.NET、PHP中的用法有的时候也略有不同,许多用户在正则表达式的学习和使用中也有着各种不同的疑问和困惑。

本次我们特邀《正则指引》图书作者余晟和ChinaUnix论坛Perl版版主flw、zhlong8、Shell版版主waker、Shell_HAT、zooyo、参与讨论,大家有什么问题也尽管问吧:)

本期话题:
1、在你的日常工作中会使用正则表达式解决什么样的问题?
2、正则表达式的用法在各个语言、脚本里面略有不同,你有什么学习经验可以分享给初学者?

活动时间:
2012年6月1日-6月20日

话题要求:
1、 要言之有物,不能低于20个字
2、 本次话题主要关注shell、perl、Python等相关语言的正则表达式技术讨论,其他问题可能不做重点。

奖项设置:

最佳交流奖:1名,奖励ChinaUnix背包一个。
积极交流奖:3名,奖励《正则指引》图书一本
参与奖:所有有效参与的用户奖励ChinaUnix社区积分20分

奖品简介:

作者:余晟
出版社:电子工业出版社
ISBN:9787121165511
上架时间:2012-5-2
出版日期:2012 年5月
开本:16开

图书简介:
《正则指引》针对作者在开发中遇到的实际问题,以及其他开发人员咨询的问题,总结出一套使用正则表达式解题的办法,并通过具体的例子指导读者拆解、分析问题。全书分为三大部分:第一部分主要讲解正则表达式的基础知识,涵盖了常见正则表达式中的各种功能和结构;第二部分主要讲解关于正则表达式的更深入的知识,详细探讨了编码问题、匹配原理、解题思路;第三部分将之前介绍的各种知识落实到6种常用语言.net、java、javascript、php、python、ruby中,不但详细介绍了语言中正则表达式的用法,更点明了版本之间的细微差异,既可以作为专门学习的教材,也可以作为有用的参考手册。

样章阅读:
http://wenku.it168.com/d_000271891.shtml

论坛徽章:
5
亥猪
日期:2013-10-15 13:41:04CU十二周年纪念徽章
日期:2013-10-24 15:41:34申猴
日期:2013-10-28 10:55:45辰龙
日期:2013-10-31 13:29:29丑牛
日期:2014-02-14 11:25:54
31 [报告]
发表于 2012-06-01 18:05 |只看该作者
正则在工作中都是用于日志文件的分析,提取,替换一些文本处理的操作还有一块就是前端js 校验用户填写信息。支持正则的有很多 常用的grep awk sed perl py都行但是有些小的地方不一样,比如awk 就不能用\d只能用[0-9],sed用+需要加-r参数等等,确实比较讨厌。这其中咱一般都是统一成用perl这样对正则支持比较全面的,而且能够写得比较简单比如一行搞定的去处理。如果正则比较简单的话就好办了,随便用哪个都行。

论坛徽章:
2
午马
日期:2015-01-27 11:22:392015年辞旧岁徽章
日期:2015-03-03 16:54:15
78 [报告]
发表于 2012-06-11 15:41 |只看该作者
回复 83# chenjintao_ii


    两个问题,
  
    1. “Binary file ./usr/bin/dbus-launch matches”
    这个问题你应该考虑,为什么你要从一个binary file里去grep一行文字,是否有这个需求?
    请参阅grep -I 选项
       -I     Process a binary file as if it did not contain matching data; this is equivalent to the --binary-files=without-match option.

       --binary-files=TYPE
              If the first few bytes of a file indicate that the file contains binary data, assume that the file is of type TYPE.  By default, TYPE  is  binary,  and
              grep  normally outputs either a one-line message saying that a binary file matches, or no message if there is no match.  If TYPE is without-match, grep
              assumes that a binary file does not match; this is equivalent to the -I option.  If TYPE is text, grep processes a binary file as if it were text; this
              is  equivalent  to  the -a option.  Warning: grep --binary-files=text might output binary garbage, which can have nasty side effects if the output is a
              terminal and if the terminal driver interprets some of it as commands.



    2. 用grep -v "No such file or directory"不能屏蔽。。。
    这两个问题有一点,你似乎没有分清 stdout和stderr ?
    如果这个分不清的话。。。那还是去打打基本功吧先。

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
85 [报告]
发表于 2012-06-12 12:19 |只看该作者

以前用过 dos 的 glob 匹配,觉得那个功能很好用,后来使用 word 时,觉得它的查找替
换功能也十分便利,还支持“弱智的正则”(这是现在的看法了,当时觉得很“高级”很NB)。
随着自己对查找(匹配)的要求越来越高,就想,要是有一种更加“聪明”更加“智能”的
搜索方法该多好啊。直到有一天偶然碰上了正则表达式,“这正是自己苦苦寻找的好东西
啊”,真是相见恨晚!

正则无处不在,完全可以这样说。它是一种搜索模式,它存在于我们每天的生活中,存在
于世界的各个角落,无时无刻。

时刻离不开正则:使用 shell 命令(如 grep, sed, awk……等等)时,编辑文本时,搜索
数据时……UNIX 下的各种工具几乎到处都可见正则的倩影,一旦了解了正则的基本知识,
就会大幅度地提高效率——操作的效率和代码的效率。甚至是当你寻找某个人的时候,其实你
也是在使用正则。

比如,你曾经编辑一个文件,现在忘了存放在哪个目录了,如何快速从千万个文件中找到它?
grep! 指定恰当的正则,grep 就会快速地帮你找到你要的文件。

你想把代码中多次出现的某个函数名修改为另一个更加合适的名字,不要愚蠢地手动修改,
编辑器都有(如果没有,你还用它干吗?)支持正则的全局替换命令,一个命令就好了。

我正在用vim写这个贴子,把中文的句号(“。”)全部误写成“.”。不用担心,不用管它,
最后用一个命令:%s/\./。/g全部替换就好了。(我的文本里不需要“.”,除非用来举例的
这几个。)

应用的例子举不胜举,但万变不离其宗,本质就是匹配(查找)。

不同的工具所支持的正则(正则引擎)也有所不同。大体上说,大同小异。

最好先易后难,从学习比较简单的 POSIX BRE 和 POSIX ERE 开始, 通过grep学习基本的
正则,对正则有一个基本的感性认识。

掌握了正则的基础后,再学习其它工具的正则就显得简单容易多了。不过,碰到问题时你
还是要参考相应工具的手册,也许该工具有本身的正则扩展或比较特殊的功能。要精通正
则,还需要不断地努力。

Perl 应该是正则之王。如果你喜欢正则,想体验正则的强悍,那你不能不了解 Perl。

论坛徽章:
0
92 [报告]
发表于 2012-06-13 22:32 |只看该作者
1、在你的日常工作中会使用正则表达式解决什么样的问题?
我用到的都是在实际场景下,正则只是其中的一点。
a) 以前公司的产品在处理日志时,需要匹配日志,解析日志中的变量,这个是最简单的,用到的正则匹配工具Regular.exe、RegexBuddy.exe、Regex Match Tracer
  1. IDS事件:
  2. <82>IDSName:msensorgiga3;EventName:snmp_uservars:bad_commname;Count:1;SIP:10.28.3.99;1052;DIP:10.28.47.17;161;Time:2005-03-18 03:50:51;Type:^ce^b4^d6^aa;Severity:^d6^d0^b7^e7^cf^d5;Bad SNMP community name from 10.28.3.99 to 10.28.47.17
  3. <82>IDSName:msensorgiga3;EventName:dns_labels:binary;Count:1;SIP:10.28.8.100;15000;DIP:210.22.14.9;53;Time:2005-03-18 03:50:31;Type:^b9^a5^bb^f7;Severity:^d6^d0^b7^e7^cf^d5;10.28.8.100 -> 210.22.14.9 id 14080 DNS label contains binary data
  4. <82>IDSName:msensorgiga3;EventName:www2_uservars:unsafe_method;Count:1;SIP:10.28.70.7;4862;DIP:10.0.241.102;80;Time:2005-03-18 03:50:22;Type:^b9^a5^bb^f7;Severity:^d6^d0^b7^e7^cf^d5;10.28.70.7 -> 10.0.241.102: Unsafe method seen: POLL
  5. <82>IDSName:msensorgiga3;EventName:tftp_opcode;Count:1;SIP:10.28.7.96;15000;DIP:221.214.148.244;69;Time:2005-03-21 17:26:40;Type:探测;Severity:中风险;10.28.7.96 -> 221.214.148.244: Suspicious opcode in TFTP transfer
  6. <82>IDSName:msensorgiga3-4507;EventName:tftp_opcode;Count:1;SIP:10.28.4.154;57777;DIP:211.244.33.95;69;Time:2005-04-03 20:22:02;Type:探测;Severity:中风险;10.28.4.154 -> 211.244.33.95: Suspicious opcode in TFTP transfer
  7. <82>IDSName:Sensor-B;EventName:snmp_uservars:bad_commname;Count:1;SIP:132.194.68.102;60856;DIP:10.28.68.121;161;Time:2007-03-21 18:44:14;Type:未知;Severity:中风险;Bad SNMP community name from 132.194.68.102 to 10.28.68.121
  8. 判别规则:
  9. <\d+>IDSName:([^;]+);EventName:([^:]+):([^;]+);Count:(\d+);SIP:([^;]+);(\d+);DIP:([^;]+);(\d+);Time:([^;]+);Type:([^;]+);Severity:([^;]+);([^;]+)
  10. <\d+>IDSName:([^;]+);EventName:([^;]+);Count:(\d+);SIP:([^;]+);(\d+);DIP:([^;]+);(\d+);Time:([^;]+);Type:([^;]+);Severity:([^;]+);([^;]+)
复制代码
b) 自定义unix系统登录日志,其中需要获取登录用户名、IP等信息时,也只是简单的使用cut、grep、awk等。嘿嘿,不过以下代码的完整文档可是我的心血。感兴趣的兄弟自行研究。
  1. # Add content in /etc/profile
  2. # Log "bash sh ksh" user login and command history
  3. up_client_ip=`(who am i|cut -d\( -f2|cut -d\) -f1)`
  4. if ( test -z "`echo $up_client_ip|awk '($1 ~/[0-9]+.[0-9]+.[0-9]+.[0-9]+/)'`" )
  5. then
  6. up_client_ip=`awk '/'$up_client_ip'/ {print $1}'  /etc/hosts`
  7. fi
  8. up_nowtime=`(date +"%Y-%m-%d %T")`
  9. logger -p user.notice -- class=\"HOST_LOGIN\" type=\"2\" time=\"$up_nowtime\" src_ip=\"$up_client_ip\" dst_ip=\"192.168.100.90\" primary_user=\"\" secondary_user=\"`id|cut -d\( -f2|cut -d\) -f1`\" operation=\"\" content=\"login successful\" authen_status=\"Success\" log_level=\"1\" session_id=\"$$\" 2>/dev/null
  10. case "$0" in
  11. -bash)
  12.         export PROMPT_COMMAND='logger -p user.notice -- class=\"HOST_COMMAND\" type=\"3\" time=\"`date +"%Y-%m-%d %T"`\" src_ip=\"$up_client_ip\" dst_ip=\"192.168.100.90\" primary_user=\"\" secondary_user=\"`id|cut -d\( -f2|cut -d\) -f1`\" operation=\"$(history 1 | { read x y; echo $y; })\" content=\"command\" authen_status=\"\" log_level=\"1\" session_id=\"$$\" 2>/dev/null;'
  13.         ;;
  14. -ksh)
  15. function log2syslog
  16. {
  17.                 logger -p user.notice -- class=\"HOST_COMMAND\" type=\"3\" time=\"`date +"%Y-%m-%d %T"`\" src_ip=\"$up_client_ip\" dst_ip=\"192.168.100.90\" primary_user=\"\" secondary_user=\"`id|cut -d\( -f2|cut -d\) -f1`\" operation=\"`fc -ln -0`\" content=\"command\" authen_status=\"\" log_level=\"1\" session_id=\"$$\" 2>/dev/null;
  18. }
  19.         trap log2syslog DEBUG;
  20.         ;;
  21. esac
  22. readonly up_client_ip
  23. readonly up_nowtime
  24. readonly PROMPT_COMMAND
复制代码
c) 公司要分析统计WEB日志中一些攻击行为,然后就有了这么一个脚本。说明下,WEB日志是以IP为目录,目录下存放日志文件,日志文件名中包含日期。keywords文件定义关键字,server_ip定义要分析的WEB日志IP。
  1. logdir=/var/log/netscaler
  2. analysedir=/var/www/html/seclog
  3. yesterday=`(date -d yesterday +"%Y-%m-%d")`
  4. today=`(date +"%Y-%m-%d")`

  5. function LOG_ANALYSE
  6. {
  7. cd $analysedir
  8. echo $SERVER_IP
  9. if [ ! -d $SERVER_IP ];
  10.         then mkdir $SERVER_IP;
  11. fi
  12. if [ ! -d $SERVER_IP/$yesterday ];
  13.         then mkdir $SERVER_IP/$yesterday;
  14.         else rm -rf $SERVER_IP/$yesterday/*;
  15. fi
  16. for VALUE in `cat keywords |egrep -v "^$|^#"|awk -F"=" '{print $2}'`;
  17.     do
  18.         KEY=`grep "=$VALUE" keywords|egrep -v "^$|^#"|cut -d\= -f1`;
  19.         grep -i "$VALUE" $logdir/$SERVER_IP/*$yesterday.log* >>$SERVER_IP/$yesterday/"$SERVER_IP"_"$KEY".result;
  20. done
  21. cd $SERVER_IP/$yesterday/
  22. awk '{print $3"\t"$9}' *.result >>analyse_"$yesterday"
  23. #sed -r 's/.* (\S+) \S+ HTTP \S+ \S+ \S+ (\S+) .*/\1 \2/'*.result >>analyse_"$yesterday"
  24. echo "url                                独立IP数                       pv">>count_"$yesterday"
  25. echo "--------------------------------------------------------------------">>count_"$yesterday"
  26. awk '{a[$2]++;if(!b[$2"_"$1]){b[$2"_"$1]=1;n[$2]++}}END{for(i in a) printf "%-45s %-20s %s\n",i,n[i],a[i]}' analyse_"$yesterday" | sort -k3n >>count_"$yesterday"
  27. echo "IP                                 访问URL数                   次数">>count_"$yesterday"
  28. echo "--------------------------------------------------------------------">>count_"$yesterday"
  29. awk '{a[$1]++;if(!b[$1"_"$2]){b[$1"_"$2]=1;n[$1]++}}END{for(i in a) printf "%-45s %-20s %s\n",i,n[i],a[i]}' analyse_"$yesterday" | sort -k3n >>count_"$yesterday"
  30. cd $analysedir
  31. }
  32. for SERVER_IP in `cat $analysedir/server_ip|egrep -v "^$|^#"`;
  33.     do LOG_ANALYSE;
  34. done
  35. cd $analysedir
  36. cat /dev/null >$analysedir/analyse_"$yesterday"_all
  37. cat /dev/null >$analysedir/count_"$yesterday"_all
  38. for SERVER_IP in `cat $analysedir/server_ip|egrep -v "^$|^#"`;
  39.     do cat $analysedir/$SERVER_IP/$yesterday/analyse_"$yesterday" >>$analysedir/analyse_"$yesterday"_all;
  40. done
  41. echo "url                                独立IP数                       pv">>$analysedir/count_"$yesterday"_all
  42. echo "--------------------------------------------------------------------">>$analysedir/count_"$yesterday"_all
  43. awk '{a[$2]++;if(!b[$2"_"$1]){b[$2"_"$1]=1;n[$2]++}}END{for(i in a) printf "%-45s %-20s %s\n",i,n[i],a[i]}' analyse_"$yesterday"_all | sort -k3n >>$analysedir/count_"$yesterday"_all
  44. echo "IP                                 访问URL数                   次数">>$analysedir/count_"$yesterday"_all
  45. echo "--------------------------------------------------------------------">>count_"$yesterday"_all
  46. awk '{a[$1]++;if(!b[$1"_"$2]){b[$1"_"$2]=1;n[$1]++}}END{for(i in a) printf "%-45s %-20s %s\n",i,n[i],a[i]}' analyse_"$yesterday"_all | sort -k3n >>$analysedir/count_"$yesterday"_all
复制代码
d) 检查日志中是否包括敏感信息,如信用卡号、身份证号等,写了个简单的脚本,就用grep、egrep。
  1. ####################################################
  2. echo "log contain ID Number:"
  3. echo "-------------------------------------------"
  4. egrep -a "\b[0-9]{6}[1|2][8|9|0][0-9]{2}0[1-9][0-3][0-9][0-9]{3}[0-9x]\b|\b[0-9]{6}[1|2][8|9|0][0-9]{2}1[0-2][0-3][0-9][0-9]{3}[0-9x]\b|\b[0-9]{6}[0-9]{2}0[1-9][0-9]{5}\b|\b[0-9]{6}[0-9]{2}1[0-2][0-9]{5}\b|持卡人证件号" */*
  5. echo
  6. echo
  7. ####################################################
  8. echo "log contain Credit card number:"
  9. echo "-------------------------------------------"
  10. #egrep  "4[0-9]{15}|4[0-9]{12}|5[1-5][0-9]{14}|6011[0-9]{12}|65[0-9]{14}|3[47][0-9]{13}|30[0-5][0-9]{11}|3[68][0-9]{12}|2131[0-9]{11}|1800[0-9]{11}|35[0-9]{3}[0-9]{11}" */*
  11. egrep -a  "\b4[0-9]{15}\b|\b4[0-9]{12}\b|\b5[1-5][0-9]{14}\b|\b6011[0-9]{12}\b|\b65[0-9]{14}\b|\b3[47][0-9]{13}\b|\b30[0-5][0-9]{11}\b|\b3[68][0-9]{12}\b|\b2131[0-9]{11}\b|\b1800[0-9]{11}\b|\b35[0-9]{3}[0-9]{11}\b|BankCardNumber" */*
  12. echo
  13. echo
  14. ####################################################
复制代码
e) 检查后门,这个用的网上现成的代码。
  1. #!/usr/bin/python
  2. #-*- encoding:UTF-8 -*-
  3. ###
  4. ## @package
  5. ##
  6. ## @author      CFC4N   <cfc4nphp@gmail.com>
  7. ## @copyright   copyright (c) Www.cnxct.Com
  8. ## @Version     $Id: check_php_shell.py 37 2010-07-22 09:56:28Z cfc4n $
  9. ###
  10. import os
  11. import sys
  12. import re
  13. import time
  14. def listdir(dirs,liston='0'):
  15.     flog = open(os.getcwd()+"/check_php_shell.log","a+")
  16.     if not os.path.isdir(dirs):
  17.         print "directory %s is not exist"% (dirs)
  18.         return
  19.     lists = os.listdir(dirs)
  20.     for list in lists:
  21.         filepath = os.path.join(dirs,list)
  22.         if os.path.isdir(filepath):
  23.             if liston == '1':
  24.                 listdir(filepath,'1')
  25.         elif os.path.isfile(filepath):
  26.             filename = os.path.basename(filepath)
  27.             if re.search(r"\.(?:php|inc|html?)$", filename, re.IGNORECASE):
  28.                 i = 0
  29.                 iname = 0
  30.                 f = open(filepath)
  31.                 while f:
  32.                     file_contents = f.readline()
  33.                     if not file_contents:
  34.                         break
  35.                     i += 1
  36.                     match = re.search(r'''(?P<function>\b(?:include|require)(?:_once)?\b)\s*\(?\s*["'](?P<filename>[^;]*(?<!\.(?:php|inc)))["']\)?\s*''', file_contents, re.IGNORECASE| re.MULTILINE)
  37.                     if match:
  38.                         function = match.group("function")
  39.                         filename = match.group("filename")
  40.                         if iname == 0:
  41.                             info = '\n[%s] :\n'% (filepath)
  42.                         else:
  43.                             info = ''
  44.                         info += '\t|-- [%s] - [%s]  line [%d] \n'% (function,filename,i)
  45.                         flog.write(info)
  46.                         print info
  47.                         iname += 1
  48.                     match = re.search(r'\b(?P<function>eval|proc_open|popen|shell_exec|exec|passthru|system)\b\s*\(', file_contents, re.IGNORECASE| re.MULTILINE)
  49.                     if match:
  50.                         function = match.group("function")
  51.                         if iname == 0:
  52.                             info = '\n[%s] :\n'% (filepath)
  53.                         else:
  54.                             info = ''
  55.                         info += '\t|-- [%s]  line [%d] \n'% (function,i)
  56.                         flog.write(info)
  57.                         print info
  58.                         iname += 1
  59.                     match = re.search(r'(^|(?<=;|=))\s*`(?P<shell>[^`]+)`\s*;', file_contents, re.IGNORECASE)
  60.                     if match:
  61.                         shell = match.group("shell")
  62.                         if iname == 0:
  63.                             info = '\n[%s] :\n'% (filepath)
  64.                         else:
  65.                             info = ''
  66.                         info += '\t|-- [``] command is [%s] in line [%d] \n'% (shell,i)
  67.                         flog.write(info)
  68.                         print info
  69.                         iname += 1
  70.                 f.close()
  71.     flog.close()
  72. if '__main__' == __name__:
  73.     argvnum = len(sys.argv)
  74.     liston = '0'
  75.     if argvnum == 1:
  76.         action = os.path.basename(sys.argv[0])
  77.         print "Command is like:\n   %s D:\wwwroot\ \n   %s D:\wwwroot\ 1    -- recurse subfolders"% (action,action)
  78.         quit()
  79.     elif argvnum == 2:
  80.         path = os.path.realpath(sys.argv[1])
  81.         listdir(path,liston)
  82.     else:
  83.         liston = sys.argv[2]
  84.         path = os.path.realpath(sys.argv[1])
  85.         listdir(path,liston)
  86.     flog = open(os.getcwd()+"/check_php_shell.log","a+")
  87.     ISOTIMEFORMAT='%Y-%m-%d %X'
  88.     now_time = time.strftime(ISOTIMEFORMAT,time.localtime())
  89.     flog.write("\n----------------------%s checked ---------------------\n"% (now_time))
  90.     flog.close()
复制代码
2、正则表达式的用法在各个语言、脚本里面略有不同,你有什么学习经验可以分享给初学者?
a) 入门看《正则表达式30分钟入门教程》,看完基本的就会了,然后用我上面说的那几个工具试试,很容易上手;
b) 要想了解的深,就得有相应的场景使你可以去不断的研究那些语法。比如在上面提到的日志匹配,在实际过程中用到比较多的有界定(通过什么来界定位置,比如\b)、零宽断言、捕获、单行、多行、不匹配大小写等,这里就不详细说了,大家用不到。
c) 不同语言中的正则表达式会有所不同,比如java、perl、shell中可以使用的都会有不同,这个看相应的说明就行了。
d) 单纯的学习正则表达式不难,更多的是结合其他语言来完成特定的任务。
e) 测试正则表达式的效率可以使用RegexBuddy.exe看详细的匹配过程,匹配次数。一般来讲能明确的就明确,比如改用\d{1,3}就不用.*等;能限定的就限定,比如\w{1,3}就不用\w+,等等。网上也有一些资料。
f) 最好有实际场景来解答,这样才学得快。

论坛徽章:
0
103 [报告]
发表于 2012-10-09 14:09 |只看该作者
都是高手.就我是菜鸟.

论坛徽章:
0
102 [报告]
发表于 2012-06-18 23:06 |只看该作者
回复 106# to407
哎,我看到特殊字符先想到的是在正则表达式里有特殊含义的字符而不是不可打印字符或者控制字符。。。

   

论坛徽章:
2
午马
日期:2015-01-27 11:22:392015年辞旧岁徽章
日期:2015-03-03 16:54:15
101 [报告]
发表于 2012-06-18 16:24 |只看该作者
回复 105# kingbigeast


    恩 第一点 我的意思是 任意可打印字符, 只要是所在命令行或者被包裹程序不需要转义的字符都可以拿来用, 甚至简单的 'a' 字符也行

    举个例子~~~

  1. -bash-3.00$ cat dbm.env
  2. export ORACLE_SID=orcl1

  3. -bash-3.00$ sed 'saORACLEaDATABASEag' dbm.env
  4. export DATABASE_SID=orcl1
复制代码

论坛徽章:
0
100 [报告]
发表于 2012-06-18 16:02 |只看该作者
本帖最后由 kingbigeast 于 2012-06-18 16:03 编辑

回复 104# to407
  • 是可以是其它字符,我没想说全,比如“?”,“|”,“.”,但非特殊字符我不明白,它们都是特殊字符啊。
  • 我不是很清楚通配符和正则表达式的区别,正则表达式里不是也有通配符么。而且这里的最长匹配和最短匹配应该是正则表达式才有的概念吧。

写得太匆忙,领教了。

论坛徽章:
2
午马
日期:2015-01-27 11:22:392015年辞旧岁徽章
日期:2015-03-03 16:54:15
99 [报告]
发表于 2012-06-18 11:02 |只看该作者
回复 101# kingbigeast


   
vim里的正则应该跟sed比较像,可能你注意到了,s替换的时候不是用/分隔的,而是下划线,这个特性我首先在sed中遇到,当模式中含有斜杠的时候特别有用。


  这边就是sed, sed的分隔符 其实可以用任意非特殊字符~~~比如abc~~

  后面这个字符串用'##'截取字符串的话, 应该是通配符"wildcard char",不算RE

论坛徽章:
49
15-16赛季CBA联赛之福建
日期:2016-06-22 16:22:002015年亚洲杯之中国
日期:2015-01-23 16:25:12丑牛
日期:2015-01-20 09:39:23未羊
日期:2015-01-14 23:55:57巳蛇
日期:2015-01-06 18:21:36双鱼座
日期:2015-01-02 22:04:33午马
日期:2014-11-25 09:58:35辰龙
日期:2014-11-18 10:40:07寅虎
日期:2014-11-13 22:47:15申猴
日期:2014-10-22 15:29:50摩羯座
日期:2014-08-27 10:49:43辰龙
日期:2014-08-21 10:47:58
98 [报告]
发表于 2012-06-17 12:12 |只看该作者
Bean_lee 发表于 2012-06-17 10:06
1、在你的日常工作中会使用正则表达式解决什么样的问题?
1 利用正则表达式解析用户输入的配置,或者配置文 ...


真是个潜水牛人啊,呵呵

论坛徽章:
1
技术图书徽章
日期:2014-04-24 15:46:21
97 [报告]
发表于 2012-06-17 10:06 |只看该作者
1、在你的日常工作中会使用正则表达式解决什么样的问题?
1 利用正则表达式解析用户输入的配置,或者配置文件里面的配置,
2 分析日志中的信息。
3 用户输入合法性的检测。比如用户输入一个IP,你必须检测用户输入的IP正确与否。

2、正则表达式的用法在各个语言、脚本里面略有不同,你有什么学习经验可以分享给初学者?
各种语言都有对正则表达式的支持,从我日常的C,Javascript,PHP, python,各种语言都支持正则表达式,
我们一向认为的不太适合解析字串的C也有对正则表达式的支持,但是C也有库来支持这个正则表达式。筒子们可以自行
百度regexec,js比较方便,有 RegExp 对象。

学习正则表达式,首先要理解正则表达式的规则,至于各种语言对正则表达式的支持,理解了正则表达式,自然也就水到渠成了。

论坛徽章:
0
96 [报告]
发表于 2012-06-17 01:08 |只看该作者
本帖最后由 kingbigeast 于 2012-06-17 01:11 编辑

学习正则表达式是从余晟翻译的《精通正则表达式》开始的,由于用vim的时发现很多时候都要用正则表达式。
从最基本的“锚点”、特殊符号,这些都是以前稍微明白一点的,而且不难上手。真正有意思的是在了解了诸如“匹配优先”,“忽略优先”,“固化分组”等等概念,还有不同引擎采用的不同思想:传统的NFA就是非确定有穷状态自动机,是表达式主导的,就是匹配的结果根据regex的增长而逐渐确定。而DFA是文本主导。每一次匹配,其实就是在文本空间做了一次搜索,不同的搜索策略的结果是一样的,就像BFS和DFS。由于NFA是表达式主导,所以表达式的质量直接关系到搜索效率。
【以上基本是我读书的心得。】
举一些我现在能想到的例子:

在调试代码的时候,会很频繁地添加和注释一些测试代码。在vim中,可以用一些键绑定特定的regex来实现:

  1. vmap <silent> <Leader>/ :s_^\(\s\)\?_\1//<CR>
  2. vmap <silent> <Leader>\ :s_^\(\s\)\?//_\1<CR>
复制代码
以上是C++里的注释和去注释,把斜杠换成#也可以在shell脚本中使用。
vim里的正则应该跟sed比较像,可能你注意到了,s替换的时候不是用/分隔的,而是下划线,这个特性我首先在sed中遇到,当模式中含有斜杠的时候特别有用。

*nux下很多工具的输出都是纯文本的,就是为了方便处理。而处理文本的工具必须要用正则表达式。
例如我想知道自己的IP,并把它赋给一个变量,首先用ifconfig得到包含本机IP的信息字符串,然后用grep找到感兴趣的行,最后用cut找到感兴趣的域:

  1. $ifconfig eth0 | grep "inet addr" | cut -d: -f2 | cut -d" " -f1
复制代码
当然这里并没用到什么高级的技巧。但有时候这个功能很需要,比如要用ffmpeg截取屏幕视频,要先知道窗口的坐标,xwininfo可以得到窗口信息,但要用grep或sed处理才能过滤出想要的结果。

再举一个Shell里用regex的例子。比如现在一直一个绝对路径,我要找到它的文件名和后缀名可以这样:

  1. $filepath=/home/bigeast/Desktop/try/te.c
  2. $filename=${filepath##*/}                #now $filename is te.c
  3. $filetype=${filename##.}                #now $filetype is c
  4. $file=${filename%*.c}                        #now $file is te
复制代码
两个#代表从做向右找最长的匹配(匹配优先),而一个%表示从右向左找最短的匹配(忽略优先)。

时间不早了,暂且写这么多,第一次上chinaunix,感觉氛围还不错。

论坛徽章:
0
95 [报告]
发表于 2012-06-15 16:23 |只看该作者
支持
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP