如果目标字符串,包含字符串X,仅1次则返回ture ,否则返回false.例如:
 目标字符串:abcabc
 字符串X:abc
 返回:false 因为包含了abc两次!
 目标字符串:abcaabc
 字符串X:abc
 返回:true 因为包含了abc1次!这样的正则怎么写啊? 

解决方案 »

  1.   


    public static void main(String[] args) { String str = "abcdefgabc";
    Pattern pattern = Pattern.compile("abc");
    Matcher matcher = pattern.matcher(str); int i = 0;
    while (matcher.find()) {
    //matcher.group();
    i++;
    }
    System.out.println(i);
    }
    能够实现楼主的要求,i即为该字符串的次数。
    仅供参考
      

  2.   


    public class TestRegex { /**
     * @param args
     */
    public static void main(String[] args) { System.out.println(test()); } private static boolean test() {
    String str = "abcdefg";

    Matcher matcher = Pattern.compile("abc").matcher(str); int i = 0;
    while (matcher.find()) {
    i++;
    }
    if (i == 1) {
    return true;
    }
    return false;
    }}呵呵,再改下。呵呵
      

  3.   

    谢谢啊。我知道这种写法啊。。我是想通过纯正则的手法啊。而且不是记录次数啊!是我没说清楚啊。sorry啊。。
    就是用纯正则表现啊
      

  4.   

    目标字符串:abcaabc
    字符串X:abc
    返回:true 因为包含了abc1次!
     这个不是也包含了2次吗?楼主的意思是不能有别的字符?
      

  5.   

    同问 5 楼的问题
    如果是楼主写错的话,根本不用正则表达式:public class Test {
        
        public static void main(String[] args) {
            String a = "abcabac";
            String b = "abc";
            System.out.println(isOnlyOne(a, b));
        }
        
        public static boolean isOnlyOne(String str, String substr) {
            if(str == null || substr == null) {
                throw new IllegalArgumentException("string is null");
            }
            if(str.length() == 0 || substr.length() == 0) {
                throw new IllegalArgumentException("string is empty");
            }
            int a = str.indexOf(substr);
            int b = str.lastIndexOf(substr);
            return (a == b && a > -1);
        }
    }
      

  6.   

    汗。。对不起打错了
    目标字符串:abcadc 
    字符串X:abc 
    返回:true 因为包含了abc 1次! 
      

  7.   

    这个用正则会很复杂,因为你不得不考虑所有的组合情况为什么不直接用split方法呢?判断split得到的数组length == 2
      

  8.   

    抱歉我忘了java中split只能接受char类型的参数
      

  9.   

    考虑另一种方案, 只是设想
    "abcabc".replaceAll("abc", "").length == "abcabc".length - "abc".length;
      

  10.   

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;public class regTest {
    public static void main(String[] args){
    String regEx="abcabc";
    Pattern p = Pattern.compile("(?<=(?<!abc))abc{1}?(?=(?!abc))");
    Matcher m = p.matcher(regEx); 
    while(m.find()) 

        System.out.println("匹配内容:"+m.group()); 
        return ;

    System.out.println("不匹配!");  }
    }测试结果:不匹配!
    把regEx改为abcadc
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;public class regTest {
    public static void main(String[] args){
    String regEx="abcadc";
    Pattern p = Pattern.compile("(?<=(?<!abc))abc{1}?(?=(?!abc))");
    Matcher m = p.matcher(regEx); 
    while(m.find()) 

        System.out.println("匹配内容:"+m.group()); 
        return ;

    System.out.println("不匹配!");  }
    }
    测试结果:匹配内容:abc
      

  11.   


    String reg1 = "((.{0,})?(abc)(.{0,})?){1}";
    String reg2 = "((.{0,})?(abc)(.{0,})?){2}";
    String str = "saabcdddddabcddabcdabcd";
    System.out.println(str.matches(reg1) && !str.matches(reg2));试试这个!
      

  12.   

    public class Test{
        public static void main(String args[]) {
         String[] strs={"abc34abc","2rabcjabcabc","abcadc"};
         String str="abc";
         String regex=".*?("+str+")(?:.*?"+str+".*)";
         for(String s : strs){
         System.out.print(s+":");
         if(!s.matches(regex)){
         System.out.println(true);
         }else{
         System.out.println(false);
         }
         }    }
    }
    F:\java>java Test
    abc34abc:false
    2rabcjabcabc:false
    abcadc:true
      

  13.   

    String regex=".*?"+str+"(?:.*?"+str+".*)";
      

  14.   

    虫子哥很久不见了啊,你的这个想法之前我也想过,不过LZ的意思应该是希望
    if(s.matches(regex)){
                    System.out.println(true);
                }else{
                    System.out.println(false);
                }
    不知道这样的正则怎么写,我写的那个很局限
      

  15.   

    重新想了一下,应该没什么问题了吧
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;public class regTest {
    public static void main(String[] args){
    String[] strs={"abc34abc","2rabcjabcabc","abcadc"};
    Pattern p = Pattern.compile("(?<=^(\\w(?<!abc))*)abc(?=(\\w(?!abc))*$)"); 
    for(String s:strs){
    Matcher m = p.matcher(s); 
    if(m.find()) 

        System.out.println("匹配内容:"+m.group()); 
        return ;

    System.out.println("不匹配!"); 
    }
    }
    }测试结果:不匹配!
    不匹配!
    匹配内容:abc
      

  16.   

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;public class regTest {
    public static void main(String[] args){
    String[] strs={"abc34abc","abcudsai","2rabcjabcabc","abcadc"};
    Pattern p = Pattern.compile("(?<=^(\\w(?<!abc))*)abc(?=(\\w(?!abc))*$)"); 
    for(String s:strs){
    Matcher m = p.matcher(s); 
    if(m.find()) 

        System.out.println("匹配内容:"+m.group()); 
    } else
    System.out.println("不匹配!"); 
    }
    }
    }
    更改一下上面的,不能直接return改为if else结构。
    测试结果:不匹配!
    匹配内容:abc
    不匹配!
    匹配内容:abc
      

  17.   


    火龙果是不是不屑回答啊。555555555555555555
    我的意思就是正则能否表达,一个字符串在目标字符串里有且有一次。这种逻辑然后举了一个例子啊!并不是需求就是这样。我的前提是1、必须用正则,而且不能采用find然后累加找到次数的方式,要直接就出结果的。
    2、如果目标字符串,包含字符串X,仅1次则返回true ,否则返回false. 例如: 
    目标字符串:abcabc 
    字符串X:abc 
    返回:false 因为包含了abc两次! 
    目标字符串:abccba 
    字符串X:abc 
    返回:true 因为包含了abc一次! 
      

  18.   


    火龙果是不是不屑回答啊。555555555555555555
    我的意思就是正则能否表达,一个字符串在目标字符串里有且有一次。这种逻辑然后举了一个例子啊!并不是需求就是这样。我的前提是1、必须用正则,而且不能采用find然后累加找到次数的方式,要直接就出结果的。
    2、如果目标字符串,包含字符串X,仅1次则返回true ,否则返回false. 例如: 
    目标字符串:abcabc 
    字符串X:abc 
    返回:false 因为包含了abc两次! 
    目标字符串:abccba 
    字符串X:abc 
    返回:true 因为包含了abc一次! 
      

  19.   


    火龙果是不是不屑回答啊。555555555555555555
    我的意思就是正则能否表达,一个字符串在目标字符串里有且有一次。这种逻辑然后举了一个例子啊!并不是需求就是这样。我的前提是1、必须用正则,而且不能采用find然后累加找到次数的方式,要直接就出结果的。
    2、如果目标字符串,包含字符串X,仅1次则返回true ,否则返回false. 例如: 
    目标字符串:abcabc 
    字符串X:abc 
    返回:false 因为包含了abc两次! 
    目标字符串:abccba 
    字符串X:abc 
    返回:true 因为包含了abc一次! 
      

  20.   


    String sReg="^.*?abc.*?abc.*?$";
    String sInput="abc,abc,adc,ac";

    System.out.println(!sInput.matches(sReg));
      

  21.   

    你拿"abcabc"去试下你的正则  输出是:"匹配内容:abc"
      

  22.   

    我来解读一下楼主的需求:对于一个字符串str,当"abc"在该字符串中出现一次且仅出现一次的时候,返回true;其他时候返回false。
      

  23.   

    String X = "abc"; // 对应lz要求的字符串X
    Pattern pattern = Pattern.compile("((?!" + X + ").)*" + X + "((?!" + X + ").)*");
    不过lz似乎要判断出现X的次数,那么选择正则是不是不明智呢……
      

  24.   

    string str[]={abcabc};
    if(str[].matches(abc)?ture:false)
    大概就是这个意思 不过不知道matches折个方法还有没有其他的方法能实现匹配只能计数一次的  不让你只能用count来计数了 不能追求你的纯正则了
      

  25.   

    这种仅有X次匹配是没办法做的,因为matches是能返回匹配和不匹配,而正则表达也没有限定次数的表达
      

  26.   

    我是从首页过来的,首页的标题是--程序员必须知道的有深度的纯正则实现字符匹配问题,想不到csdn的编辑,也成标题党了,真是世风日下,技术圈子,也充满了世俗 
      

  27.   

    目标字符串:abcaabc
    字符串X:abc
    返回:true 因为包含了abc1次! 我怎么看目标字符串都是2次呢?
    abcaabc 
    abc a abc难道不是2次吗?
      

  28.   

    紫竹。。人家说了打错了
    正则锻炼的是一个人的逻辑思维能力,其实有点像小时候的找规律我有几个问题让楼主帮我吧
    1.一个句子里只能有1个a的正则
    2.一个句子里只能有单个a,不允许出现aa这样的正则
    其实一个a跟abc的情况是类似的,我们可以把他当做一个集合来看。。当然了,在正则的表达里还是有不同的。
    其实如果掌握了正则所有的语法,这个问题很简单
      

  29.   


    我也是这么点进来的,而且这种事情在csdn的主页不止一次的发生过~~~严重BS这些标题党~~~
      

  30.   


    var regex=/(abc)(?!.*+\1)/;
      

  31.   

    var regex=/(abc).*?(?=\1)/;//取反
      

  32.   


    X > 1(即x=2,3,4....)
      

  33.   

     if(S.matches(".*?(abc).*?(abc).*?")){
     System.out.println(false);
     }
     else{
     System.out.println(true);
     }
      

  34.   

    错了。
     if(S.matches(".*?(abc).*?(abc).*?")){
     System.out.println(false);
     }
     else{
     if(S.matches(".*?(abc).*?")){
     System.out.println(true);
     }
     else{
     System.out.println(false);
     }
     }
      

  35.   

    ^abc$|^(abc)((?!\1)\w)+
     解释:
    ^abc$ #匹配仅仅包含abc的字符串
    |  #或者
    ^(abc)((?!\1)\w)+ #以a开头,后面是bc,abc后面不能再含有"abc”的字符串
      

  36.   

     居然不能编辑自己的帖子?
    需要的知识:分组,反向引用,顺序否定环视
    可以在这里测试 http://tools.netshiftmedia.com/regexlibrary/#
      

  37.   

    环视不适用于表达式匹配内容不定长的情况。(abc).*) 或者(.*(abc))均在不适用之列。
      

  38.   


        String regex = "(?:a(?!bc)|[^a])*abc(?:a(?!bc)|[^a])*";
        System.out.println("abc".matches(regex));
        System.out.println("abc1234".matches(regex));
        System.out.println("1234abc".matches(regex));
        System.out.println("1234abc1234".matches(regex));
        System.out.println("1a2b3cabc".matches(regex));
        System.out.println("abc1a2b3c".matches(regex));
        System.out.println("aabc".matches(regex));
        System.out.println("babc".matches(regex));
        System.out.println("cabc".matches(regex));
        System.out.println("bcabc".matches(regex));
        System.out.println("acabc".matches(regex));
        System.out.println("abca".matches(regex));
        System.out.println("abcb".matches(regex));
        System.out.println("abcc".matches(regex));
        System.out.println("abcab".matches(regex));
        System.out.println("abcac".matches(regex));
        System.out.println("abcbc".matches(regex));
        System.out.println("=========");
        System.out.println("".matches(regex));
        System.out.println("1234".matches(regex));
        System.out.println("abcabc".matches(regex));
        System.out.println("abc1234abc".matches(regex));
        System.out.println("1234abcabc".matches(regex));
        System.out.println("abcabc1234".matches(regex));
        System.out.println("abcaabc1234".matches(regex));
        System.out.println("abcababc1234".matches(regex));
        System.out.println("1aabccabc1234".matches(regex));
      

  39.   

    说明X的左右允许出现N(N>=0)个字符,这些字符可以是
    1 X.charAt(0)以外的字符,
    2 X.charAt(0),但是这个字符的后面不允许紧跟X.substring(1)
      

  40.   

    while (m.find()) {
    i++;
    if (i > 1)
    return false;
    }
    这样就可以少循环了
      

  41.   


    我也是这样过来的,确实没见到什么有创意的,无论是问题还是回复
    其实很简单的一个需求,就是一个顺序环视的运用,被考虑复杂了而已
    当然,对于楼主这个不是需求的需求而言,从哪方面来说,都没必要用正则,除非有实际应用场景需要
    如果X是变量,需要考虑正则中元字符的转义问题,.NET中提供了Regex.Escape方法,JavaScript中有escape函数,我不太了解Java,估计应该也有相应的方法的
    String[] test ={"abcabc","abcadc", "abc\nabc"};
    String X="abc";
    String reg="^(?is)(?:(?!" + X + ").)*" + X + "(?:(?!" + X + ").)*$";
    for(String s : test){
        Matcher m = Pattern.compile(reg).matcher(s);
        if(m.find()){
            System.out.println("源字符串:" + s + " 匹配结果: " + true);
        }else{
            System.out.println("源字符串:" + s + " 匹配结果: " + false);
        }
    }
    /*输出
    源字符串:abcabc 匹配结果: false
    源字符串:abcadc 匹配结果: true
    源字符串:abc
    abc 匹配结果: false
    */
      

  42.   


    关于escape,是java.util.Pattern.quote(String)
      

  43.   

    呵呵,想不到这个讨论的还挺热烈。一个正则是可以解决的。
    其实不难想,只要知道怎么排除指定字符串就能解决了。package com.me.app;import java.util.regex.Pattern;public class MainTest {    public static void main(String[] args) {
            String regex = "((?!abc).(?<!abc))*abc((?!abc).(?<!abc))*";
            String testInput = "abcadc";
            // print "true"
            System.out.println(Pattern.compile(regex).matcher(testInput).matches());
            testInput = "abcabc";
            // print "false"
            System.out.println(Pattern.compile(regex).matcher(testInput).matches());    }}
    看下这个帖子2楼的回答
    http://topic.csdn.net/u/20090602/19/af06ae0f-db2f-45d8-8a3d-e5ca7e8aa8c3.html
      

  44.   


    其实以(?!abc)再加(?<!abc)这种方法来匹配,不如只用(?!abc),然后前后加“^”和“$”方式来限定的好
    一是可读性问题,这个正则作用和66楼写的一样,但能读懂的怕是不多
    二是匹配效率问题,每个字符都要做两次判断,而逆序环视的效率通常是不高的,而且由于没有限定起始符,所以要遍历尝试匹配所有位置,源字符串越复杂,尝试匹配的迭代次数就越多;而用“^”和“$”方式来限定,绝大多数正则引擎都对“^”进行了优化,遇到“^”时,如果位置0处匹配失败,则不会继续尝试匹配其它位置,效率上会提升很多
      

  45.   

    确实,^((?!abc).(?<!abc))*abc((?!abc).(?<!abc))*$效率比^((?!abc).)*abc((?!abc).)*$差了好多,当测试字符串长度在200-300的时候,前者比后者慢了差不多30-40%。
    而且从逻辑上讲
    ((?!abc).)*应该已经确保了第一个abc不会匹配到,因而没有必要逆向
      

  46.   


    VB.NET        Dim X As String = "abc"
            X = Regex.Escape(X)
            Dim p As String = "^(?is)(?=.*" & X & ".*)(?!(?:.*" & X & ".*){2,})"        Dim input As String = "abc abc  aabc"
            Dim isOk As Boolean = Regex.IsMatch(input, p)
      

  47.   

    使用惰性匹配呀!!{1}?这个就代表恰好出现一次。思路(匹配包涵abc的正则){1}?
      

  48.   

       Pattern p = Pattern.compile("(?<=(?<!abc))abc{1}?(?=(?!abc))");
      

  49.   

    没看懂,而且似乎只能匹配“abc”
      

  50.   

    这个是尽量少的匹配,像abcabc,(abc){1}?可以两次匹配出来abc
      

  51.   


    然后呢?恐怕没你想的那么简单与{2},{100}不同,{1}写与不写一个样,其次,为了能够让abc在中间的文字也能被匹配(?:X)*是必须的(这里的X不是LZ那个X),而此处的X必然涉及到lookahead & lookbehind
      

  52.   

    和我那天晚上写的第一个一样,这个正则的意思是匹配前面不是abc和后面不是abc的位置上游字符串abc
    只能判断abcabc这样两个abc挨着的,如果abcdabc就无法判断了,很有局限性
    (?<=^(\\w(?<!abc))*)abc(?=(\\w(?!abc))*$) 
     这是我那天晚上写的第二个,写了好长时间,但是只有abcabc这种连在一起的不能判断,其他应该都行,我看了上面的那个正则
    String regex="((?!abc).(? <!abc))*abc((?!abc).(? <!abc))*";
    不太明白为什么可以匹配abcabc,匹配第一个abc后面紧跟的那个a不满足((?!abc).(? <!abc))
    同理匹配第二个abc,而前面那个c也不满足="((?!abc).(? <!abc))*
      

  53.   

    整理上面的,经测试,似乎就下面两个满足需求
    String reg1 = "^(?:(?!abc).)*abc(?:(?!abc).)*$";
    String reg2 = "((?!abc).(?<!abc))*abc((?!abc).(?<!abc))*";
      

  54.   

     
    (?<=^(\\w(?<!abc))*)abc(?=(\\w(?!abc))*$) 是可以匹配abcabc的
    shine333的代码在abcabc的测试中返回false是因为Java RegEx matcher.matches有其内在的约束。
    matcher.matches表示正则表达式必须的完全匹配目标字符串,也就是从字符串的开头到结尾都要匹配。
    如果使用matcher.find  来做同样的测试。
    String regex = "((?!abc).(?<!abc))*abc((?!abc).(?<!abc))*"; 
    testInput = "abcabc";
    Matcher m = Pattern.compile(regex).matcher(testInput);
    while(m.find()) {
    System.out.println(m.group()); 
    }
    输出为
    abc
    abc
    可以看出((?!abc).(?<!abc))*abc((?!abc).(?<!abc))*是可以匹配abcabc的一部分但不是完全匹配。
      

  55.   


    现在LZ的需求是直接用match,也就是/^regex$/ , 而不是统计find的次数,如果统计find的次数,还需要你那么复杂的表达式吗,直接统计find了几次"abc"就可以了
      

  56.   

    Python 2.6.2 (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)] on
    win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import re
    >>> s1 = 'abcdefg'
    >>> s2 = 'abcxxabc'
    >>> print re.match(r'(abc).*?\1', s1) == None
    True
    >>> print re.match(r'(abc).*?\1', s2) == None
    False
    >>>
      

  57.   

    嗯,这个应该是了
    (?>(^.*?)(abc))(?(.*abc)(?!))