免费注册 查看新帖 |

Chinaunix

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

允许少量替换的字符串的正则表达式怎么写? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2013-07-04 11:09 |只看该作者
黑色阳光_cu 发表于 2013-07-04 09:22


非常感谢,看到了希望。这个貌似挺好用。不过可能像上面的几位说的,需要一些限定条件。

至少有5个G开头,不同G片段之间的间隔要<=2个其它字符的时候才连接。

比如按你上面的代码,这种也会被挑出来 “GABCDGGGGGGXGGGGXGGGGGGXGXXXG”
我希望得到的是这样的: “GGGGGGXGGGGXGGGGGGXG”
  1. my $str = "ABCD----GABCDGGGGGGXGGGGXGGGGGGXGXXXG----ABCDBABDABDC";
  2. if ($str =~ /((?:G+[A-FH-Z]+)*G+)/) {
  3.     print $1, "\n";
  4. }

  5. if ($str =~ /((?:G{5,}[A-FH-Z]{0,2})*G+)/) {
  6.     print $1, "\n";
  7. }
复制代码
我改了一下,但是得到的结果不是我想要的:
GABCDGGGGGGXGGGGXGGGGGGXGXXXG
G -- 我希望得到“GGGGGGXGGGGXGGGGGGXG”

能帮我看看吗?谢谢!

论坛徽章:
0
12 [报告]
发表于 2013-07-04 11:13 |只看该作者
afukada 发表于 2013-07-03 13:04
這個問題要處理OK

只是需要一些條件


对,你说的对,条件是这样的:
至少要以5个G开头
不同G片段之间插入最多2个其它字符
最终取得的片段长度要至少要有8

比如这些:
GGGGGXXG --可以
GGGGGXXX -- 不行
GGGGGXXGGXXGXGG --可以

如果这种可以筛选出来也更好:GXGGGGGXXG -- 这种不是以5个G开头,但是因为中间有5个G,所以可以延伸到两端。但我想这种正则表达式可能很难写。
简单地说,就是一串G中,至少要有一串是5个G的,不同G片段间只能含少于2个的其它字符。

希望我讲明白了。

论坛徽章:
0
13 [报告]
发表于 2013-07-04 11:22 |只看该作者
回复 7# lhohoz

谢谢。代码很精炼,试了下,还差一点就好了。
  1. my $str = "ABCD----GXXXXXGGXGGGGGGXGGGGXGGGGGGXGXXXG----ABCDBABDABDC";
  2. if ($str =~ /((?:G+[A-FH-Z]+)*G+)/) {
  3.     print '*1*', $1, "\n";
  4. }

  5. if ($str =~ /((?:G{5,}[A-FH-Z]{0,2})*G+)/) {
  6.     print '*2*', $1, "\n";
  7. }

  8. if ( $str =~ /((G.).*\2)/ ) {
  9.   print '*3*', $1, "\n";
  10. }

  11. if ($str=~/(G+[^G]?){1,}/) {
  12.   print '*4*', $1, "\n";
  13. }

  14. if ($str=~/([XA]*G+)/) {
  15.   print '*5*', $1, "\n";
  16. }

复制代码
我一一试了上面几位的代码。最后结果是这样的。你的是第3种。

*1*GXXXXXGGXGGGGGGXGGGGXGGGGGGXGXXXG
*2*G
*3*GXXXXXGGXGGGGGGXGGGGXGGGGGGXGX
*4*GX
*5*G

你知道怎么能把前面的 GXXXXX这一段去掉吗? 因为这个G跟后面的GG中间隔了5个X,多于2个。不能加进来。

论坛徽章:
0
14 [报告]
发表于 2013-07-04 14:42 |只看该作者
本帖最后由 黑色阳光_cu 于 2013-07-04 15:11 编辑
yisn 发表于 2013-07-04 11:09
非常感谢,看到了希望。这个貌似挺好用。不过可能像上面的几位说的,需要一些限定条件。

至少有5个G ...
  1. #!/bin/env perl

  2. use strict;
  3. use warnings;

  4. while (my $line = <DATA>) {
  5.     my ($str) = split(/\s+/, $line);
  6.     if ($str =~ /(?<!G)(?=G(?:(?![A-FH-Z]{3,})[A-Z]){6,}G)((G+[A-FH-Z]{0,2})*G{5,}[A-FH-Z]{0,2}(?2)*)(?<=G)/) {
  7.         print "$str => $1\n";
  8.     }
  9.     else {
  10.         print "$str => null\n";
  11.     }
  12. }

  13. __DATA__
  14. GABCDGGGGGGXGGGGXGGGGGGXGXXXG
  15. GGGGGXGXXXXXGGGGGXG
  16. GGXGGXGGXGGXXXGGGGG
  17. GGGGGXXGX --可以
  18. GGGGGXXG --可以
  19. GGGGGXXX -- 不行
  20. GGGGGXXGGXXGXGG --可以
  21. ABCD----GXXXXXGGXGGGGGGXGGGGXGGGGGGXGXXXG----ABCDBABDABDC
复制代码

论坛徽章:
0
15 [报告]
发表于 2013-07-04 18:48 |只看该作者
回复 13# yisn


    有点复杂,目前水平解答不能,另外楼上已回答了

论坛徽章:
1
15-16赛季CBA联赛之北控
日期:2016-08-05 14:22:52
16 [报告]
发表于 2013-07-04 19:18 |只看该作者
高手啊,能解释一下正则部分吗?回复 14# 黑色阳光_cu


   

论坛徽章:
1
15-16赛季CBA联赛之北控
日期:2016-08-05 14:22:52
17 [报告]
发表于 2013-07-04 19:19 |只看该作者
14楼的 正则部分, 哪位高手解读一下啊,谢谢,学习学习~

论坛徽章:
0
18 [报告]
发表于 2013-07-04 19:22 |只看该作者
没有抠不出来的数据 只有描述不清的条件

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
19 [报告]
发表于 2013-07-05 02:16 |只看该作者
非常感谢,这个挺好用。

论坛徽章:
0
20 [报告]
发表于 2013-07-08 20:35 |只看该作者
回复 14# 黑色阳光_cu


非常感谢大神,虽然我完全看不懂这段,但是运行结果是可用的。

不过我在windows下用perl是可以出正确结果的。在一个linux服务器下就出错了,错误是:
Sequence (?2...) not recognized in regex; marked by <-- HERE in m/(?<!G)(?=G(??![A-FH-Z]{3,})[A-Z]){6,}G)((G+[A-FH-Z]{0,2})*G{5,}[A-FH-Z]{0,2}(?2 <-- HERE )*)(?<=G)/ at polyA2.pl line 18.

是perl版本的原因吗? linux下的v5.8.8 ; windows下的是v5.10.1

如果是的话,(?2) 这里有没有换一种正则表达式呢? 因为要运行的程序必须在linux下的v5.8.8 运行(那个是人家的服务器没办法自己去安装新perl)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP