• 感觉文章和回复都不错,转载了用正则表达式找出不包含连续字符串abc的单词


    写过一篇"正则表达式30分钟入门教程",有读者问:
    [^abc]表示不包含a、b、c中任意字符, 我想实现不包含字符串abc应该如何写表达式?
    就我自己而言,这个问题最简单的解决方法是使用编程语言的配合,找出那些包含abc的,剩下的就是不包含的了——懒人的风格。但我写的是教程,读者未必都有编程的基础,有些只是使用一些工具从txt文档中抽取出一些信息,所以要回答还是必须完全通过正则表达式来完成。

    于是打开了RegexTester,开始试验,先是试了使用((?'test'abc)|.)*(?(test)(?!))(含意是:查找abc,或任意的字符,如果找到了abc,就把它存入命名为test的组里,到最后检查test组里是否有内容,如果有就匹配失败,相关说明见教程),结果是"abc","aabc","abcd","aa"都能通过测试,看来是到最后测试到test组存在后又回溯了,此解决方案不可行。

    然后又试了(.(?!abc))*(找出所有后面不是abc的字符),结果是"abc","abcd"通过测试,"aabc"则只截取了后面的"abc",显然不行。

    那加强条件试试:((?<!abc).(?!abc))*(找出所有前面和后面都不是abc的字符),结果是所有包含abc的字符串都只截取了里面的"abc",不包含abc的则直接通过。

    现在看来有点戏了,但是怎么把那些内部包含abc的字符串过滤掉呢?这个问题换句话说也就是怎么匹配整体而不是部分呢?现在需要明确用户的需求了:如果用户想要找的是单词,那就在表达式的两端加上\b,如果要找的是行,就加上^$。由于用户的问题没有明确说明,我就当作是单词吧。

    于是等到了这样的表达式:\b((?<!abc).(?!abc))*\b,经过测试,这个表达式能匹配所有不包含abc的单词,以及单词abc。

    怎么排除单词abc?经过一番思考,最后我认为判断单词是否以a开头的方式最为方便:\b(a(?!bc)|[^a](?!abc))((?<!abc).(?!abc))*\b(要么以后面不是bc的a开头,要么不以a开头,除了开头后面所有的字符必须前面和后面都不是abc)。经过测试,完全满足要求,Bingo!

    使用正则表达式查找不包含连续字符串abc的单词,最终结果:\b(a(?!bc)|[^a](?!abc))((?<!abc).(?!abc))*\b
    ----------------
    更新:根据maple的评论,更简洁的作法是
    :
    \b((?!abc)\w)+\b

    posted on 2007-02-15 23:07 deerchao 阅读(2759) 评论(18)  编辑 收藏

    评论

    #1楼 221.221.165.* 2007-03-26 13:16 maple [未注册用户]

    用这个不也可以么?

    ((?!abc).)*?   回复  引用    

    #2楼 [楼主] 2007-03-26 14:12 deerchao      

    @maple
    我试了一下,但是((?!abc).)*?好像什么也匹配不到吧?   回复  引用  查看    

    #3楼 221.221.165.* 2007-03-26 15:54 maple [未注册用户]

    两头加上\b
    和你的表达式结果差不多
    不过要匹配出单个单词,还需要修改   回复  引用    

    #4楼 221.221.165.* 2007-03-26 15:57 maple [未注册用户]

    不好意思,应该是
    \b((?!abc).)*\b

    呵呵,多写了个问号   回复  引用    

    #5楼 221.221.165.* 2007-03-26 16:18 maple [未注册用户]

    再试试这个表达式吧

    \b((?!abc)\S)+?\b

    不知道我对题意的理解对不对,这个应该可以匹配出不包含abc的单词,当然abc这个单词也会排除   回复  引用    

    #6楼 [楼主] 2007-04-02 10:56 deerchao      

    不错,您的这个表达式能达到同样的效果,而且更简洁。   回复  引用  查看    

    #7楼 222.75.41.* 2007-04-04 11:43 apple [未注册用户]

    您好,受益匪浅,但是我想匹配3-5个以字母或数字开头的字串,其中不包括http,这样写却什么也匹配不到,请教!!
    /^[a-zA-Z0-9]{3,5}b((?!http)\S)+?$/   回复  引用    

    #8楼 [楼主] 2007-04-04 14:17 deerchao      

    您的表达式中间是不是多了一个b?
    如果前面3-5个字母或数字也不能包含http,你可以使用:
    ^((?!http)[a-zA-Z0-9]){3,5}((?!http)\w)*$
    如果前面可以包含http你可以使用:
    ^([a-zA-Z0-9]){3,5}((?!http)\w)*$

    注:我是使用.Net的引擎进行测试的,也许在javascript引擎下结果不同。   回复  引用  查看    

    #9楼 222.75.41.* 2007-04-04 15:31 apple [未注册用户]

    非常感谢你及时的回复,.Net的引擎有点不同,呵呵,不行,不过楼上的朋友给我了一点启发:\b((?!http)\S)+?\b;但是如何限定长度呢??   回复  引用    

    #10楼 [楼主] 2007-04-04 15:41 deerchao      

    我试了一下,javascript应该也可以啊:

    test.htm
    <script>
    var valid="abcdefgh";
    var invalid="acdsihttp";

    var reg=/^((?!http)[a-zA-Z0-9]){3,5}((?!http)\w)*$/ ;
    alert(reg.test(valid));
    alert(reg.test(invalid));
    </script>   回复  引用  查看    

    #11楼  2007-10-22 23:50 Felix      

    请教一个困扰我多次的问题,虽然类似,但我硬是没搞出来

    已知:<[^>]+>可以匹配所有HTML标签,从而通过替换标签内容去掉这些标签形成纯粹的文本

    但我想在匹配替换时排除<img /> 和 <a >xxx</a> 这两个标签从而让其在HTML文档中得到保留,却不知如何来写,希望能帮我研究研究,不胜感激!!   回复  引用  查看    

    #12楼 [楼主] 2007-10-23 02:41 deerchao      

    @Felix
    <(?!(/?(img|a)\b))[^>]*>

    匹配<html><a href="#">xxx</a><img /> <img></img><div id="aaa">xyz</div></html>的结果:
    <html>
    <div id="aaa">
    </div>
    </html>   回复  引用  查看    

    #13楼  2007-10-23 10:45 Felix      

    楼主真是非常的生猛,测试通过了,感谢!!   回复  引用  查看    

    #14楼  2007-10-23 11:41 Felix      

    楼主能否加我的MSN或Gtalk有事相商
    lf1981##msn、com
    Gtalk同理   回复  引用  查看    

    #15楼 207.46.55.* 2007-11-27 12:58 蜜桃 [未注册用户]

    有用!但是看不懂
    欢迎来蜜桃玩
    http://www.meetao.cn/   回复  引用    

    #16楼 118.144.40.* 2008-04-19 13:51 sonic_andy [未注册用户]

    ([^a]|a[^b]|ab[^c])   回复  引用    

    #17楼 124.227.192.* 2008-05-29 10:43 初学者ZXYLXW [未注册用户]

    如果我想找出字符串中有abc,但排除有@abc的如何做呢?
    比如说在.NET使用ACCESS"伪储存过程"中
    我想替换 "abc" = "@abc" 中前面一个abc为"中文字段名"
    变成 "中文字段名" = "@abc" ,请指教!   回复  引用    

    #18楼 123.120.174.* 2008-08-18 11:54 booker [未注册用户]

    你好博主,我用用vim处理log,现在我想只保留用户名是TEMP的log记录,可是VIM中好像没有?!这样的正则表达式,我用:
    /^.* \(TEMP\)\{0}.*$

    结果无法匹配,不知道博主有没有什么好办法?谢谢   回复  引用   

  • 相关阅读:
    HTML元素盒模型
    对git使用的初步总结
    在windows上,使用虚拟机安装苹果操作系统
    C++多例模式下对Instance的使用
    C++中的Inline函数的使用
    gitbash安装与使用
    C++中的Inline函数
    git bash下添加忽略文件列表
    C++数据类型(data type)介绍
    RFID会议签到系统总结(六)――系统配置(下)
  • 原文地址:https://www.cnblogs.com/vagerent/p/1284189.html
Copyright © 2020-2023  润新知