免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: send_linux
打印 上一主题 下一主题

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

论坛徽章:
0
91 [报告]
发表于 2012-06-13 21:52 |只看该作者
大家好,我是《正则指引》的作者余晟,抱歉来晚了,看大家讨论热火朝天,我先浏览一遍,再和各位讨论。

论坛徽章:
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) 最好有实际场景来解答,这样才学得快。

论坛徽章:
24
15-16赛季CBA联赛之北京
日期:2018-08-17 18:43:33技术图书徽章
日期:2018-08-22 12:53:57技术图书徽章
日期:2018-08-22 12:54:20技术图书徽章
日期:2018-08-22 12:54:3015-16赛季CBA联赛之福建
日期:2018-10-19 16:58:1619周年集字徽章-庆
日期:2019-08-27 13:28:5619周年集字徽章-19
日期:2019-08-27 13:31:2619周年集字徽章-19
日期:2019-08-27 13:31:2615-16赛季CBA联赛之同曦
日期:2019-09-05 12:03:2819周年集字徽章-周
日期:2019-09-06 18:54:5415-16赛季CBA联赛之上海
日期:2018-07-25 11:55:2615-16赛季CBA联赛之青岛
日期:2018-07-10 14:13:18
93 [报告]
发表于 2012-06-14 17:58 |只看该作者
可以说一切表达皆正则么? 正则告诉我们我们的表达都是有规律可循的,都符合一定的模式,通过正则匹配,我们可以找到我们想要的藏在茫茫互联网中的一切东西,网页抓取,数据整理,这都离不开正则

說得好。

论坛徽章:
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
94 [报告]
发表于 2012-06-15 13:58 |只看该作者
yurii 发表于 2012-06-13 21:52
大家好,我是《正则指引》的作者余晟,抱歉来晚了,看大家讨论热火朝天,我先浏览一遍,再和各位讨论。


余老师,神龙见首不见尾啊,呵呵,又不见啦

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

论坛徽章:
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,感觉氛围还不错。

论坛徽章:
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 对象。

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

论坛徽章:
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 利用正则表达式解析用户输入的配置,或者配置文 ...


真是个潜水牛人啊,呵呵

论坛徽章:
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

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

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

写得太匆忙,领教了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP