免费注册 查看新帖 |

Chinaunix

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

正则求助 [复制链接]

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-10-28 21:10 |只看该作者 |倒序浏览
本帖最后由 sunzhiguolu 于 2016-10-28 21:16 编辑

看了篇帖子, 内容如下:
提取6种特征码:  数字0    数字70    汉字   字母数字混合    时间    1个或2个数字和汉字    共6种
要求: 取反 提取
数字0
z24*   0   状:   |频
5184   0   状:   |频

数字70
t23 70 | 13:57:33|
1cd 70 | 13:47:34|
1an1 70 12 1
a458 70 12 2

汉字
8h605  龙   态:
2805    龙    态:

字母数字
288yj   a8   1 17
132j    2k   1 17
5dia    x6   0 0

时间
ZBNM   11:42:47   2
l20    8:47:01   11
cma    11:52:46   1
y1000   11:11:23   2

1个或2个数字和汉字
h605 65龙  态:
=6-4.  67龙  态:
560.  8龙   态:
805   2龙   态:
上面部分根据我写的代码,可以提取出来
下面部分是不符合条件的,也就是这次我要求取反的。(请根据我写的代码修改成取反)

bq20    964313  未  62
jbb@    4285     未   61
952755sy   95120    已    53
CA20        653    0    状线
|   |   |   21:43:32
|   |   |   06:25:22


论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
2 [报告]
发表于 2016-10-28 21:15 |只看该作者
本帖最后由 sunzhiguolu 于 2016-10-28 21:21 编辑

我的代码如下:

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. binmode (STDOUT, ':encoding(utf8)');

  5. my $rgxTime = qr /(?:\d\d?)(?::\d\d?){2}/;
  6. my $rgxTimeCn = qr /7?0|(?:\d\d?)?[\x{4E00}-\x{9FA5}]++/;
  7. my $rgxAlpha = qr /(?=.*?\d)(?=.*?[a-z])[a-z\d]++/;

  8. while (<DATA>){
  9.     my $line = $_;
  10.     local $_ = (split)[1];
  11.     next if (/\A(?:$rgxTime|$rgxTimeCn|$rgxAlpha)\z/i);
  12.     print $line;
  13. }

  14. __DATA__
  15. z24*   0   状:   |频
  16. 5184   0   状:   |频
  17. t23 70 | 13:57:33|
  18. 1cd 70 | 13:47:34|
  19. 1an1 70 12 1
  20. a458 70 12 2
  21. 8h605  龙   态:
  22. 2805    龙    态:
  23. 288yj   a8   1 17
  24. 132j    2k   1 17
  25. 5dia    x6   0 0
  26. ZBNM   11:42:47   2
  27. l20    8:47:01   11
  28. cma    11:52:46   1
  29. y1000   11:11:23   2
  30. h605 65龙  态:
  31. =6-4.  67龙  态:
  32. 560.  8龙   态:
  33. 805   2龙   态:
  34. bq20    964313  未  62
  35. jbb@    4285     未   61
  36. 952755sy   95120    已    53
  37. CA20        653    0    状线
  38. |   |   |   21:43:32
  39. |   |   |   06:25:22
复制代码

我想请教下大家, 我的匹配是否满足筛选条件. 请大家指点, 谢谢大家...
另外, 也请大家给些改进的意见. 再次感谢大家...

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
3 [报告]
发表于 2016-10-30 01:51 |只看该作者
问题论述不清:根据筛选结果看,字母数字混合,实际上是以数字开始,小写字母随后的组合。

时间的正则是: (?:[1-9][0-9]|[1-9])(?::[0-9]{2}){2}, 09:1:2 不是符合的匹配

另外,取反,一般的含义是操作二进制数的一个计算,对待字符串的取反,不知道是什么东西。

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
4 [报告]
发表于 2016-10-30 10:22 |只看该作者
回复 3# 104359176
问题论述不清:根据筛选结果看,字母数字混合,实际上是以数字开始,小写字母随后的组合。
还是大神法眼, 其实我就想匹配字母数字混合的情况. (不必考虑以数字还是字母开头的问题)
不过不依靠环视, 如何匹配一行中只包含字母数字混合的字符串.


论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
5 [报告]
发表于 2016-10-30 10:26 |只看该作者
我非常喜欢正则, 对于非常简单的情况还会匹配, 稍微有点难度表达式就不知道从哪里下手了. 还请大家指点, 谢谢大家.
其他情形不必考虑, 只考虑字符串中仅能包含字母数字的情况就好.

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
6 [报告]
发表于 2016-10-30 12:09 |只看该作者
正则表达式想要降低复杂度,有几个办法:
1. 启用 xms 模式,增加空格和相应注释


  1. /
  2.   7?0              # 70 or 0
  3.   | (?:\d\d?)?  #  00 or 0 or nothing
  4.   [\x{4E00}-\x{9FA5}]++  // Hanzi
  5. /
复制代码


2,使用正则表达式内插

  1. my $num = qr/\d+/;
  2. my $alpha = qr/[a-zA-Z]+/;
  3. my $num_or_alpha = qr/$num|$alpha/;
复制代码


3. 复用正则表达式:
CPAN 上有许多关于正则表达式定义的模块,例如:Regexp::Common, 里面定义了许多常用的正则表达式描述,这些表达式都经过了多次的测试,十分的稳定。

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
7 [报告]
发表于 2016-10-30 12:37 |只看该作者
回复 6# 104359176
大神 您说的都对, 可就是没有我想要的表达式. (表达式内插, 的确可以增强可读性)

论坛徽章:
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
8 [报告]
发表于 2016-10-30 13:38 |只看该作者
本帖最后由 jason680 于 2016-10-30 13:49 编辑

回复 2# sunzhiguolu

How about this way...

#  for 70 or 0
my $sRE_70_0 = qr/70|0/;

#  for Num + Han(汉字) or Han only
my $sRE_N_CN = qr /\d*\p{Han}+/;

#  for Num + Str, ex:   a8     or   2k
my $sRE_N_S  = qr /[a-zA-Z]+\d+|\d+[a-zA-Z]+/;

#  for time, ex: 00:00:00(0:0:0) to 23:59:59
my $sRE_Time = qr /(?:2[0-3]|[01]?[0-9]):[0-5]?[0-9]:[0-5]?[0-9]/;

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
9 [报告]
发表于 2016-10-30 14:14 |只看该作者
本帖最后由 sunzhiguolu 于 2016-10-30 14:21 编辑

回复 8# jason680
#  for Num + Str, ex:   a8     or   2k
my $sRE_N_S  = qr /[a-zA-Z]+\d+|\d+[a-zA-Z]+/;

大神 您的这个表达式 好像只能适用字符串中 英文字母后面紧跟至少一个数字 或者 数字后面紧跟至少一个英文字母 (不区分大小写) 而不是全部由字母数字字符组成.
如:
ab1@3
0ab中

另外, SHELL 板块中您用 awk 程序逻辑进行判断由字母数字构成的字符串就能满足我上面说的条件. 这个好像简单了点吧???




求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
10 [报告]
发表于 2016-10-30 14:14 |只看该作者
想建立自己的正则表达式集合,就建立一个模块,定期更新,CPAN 上有许多类似的模块。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP