现有一字符串:
String str = "aaa[bbb[ccc,ddd[eee,fff]],ggg[hhh,iii]]";要求,取出所有类似 xxx[xxx,xxx] 结构的字符串 ,当然,这个最后的结果应该是 
aaa[bbb[ccc,ddd[eee,fff]],ggg[hhh,iii]]
bbb[ccc,ddd[eee,fff]]
ddd[eee,fff]
ggg[hhh,iii]求一正则表达式,能将这个字符串分割成以上结果!

解决方案 »

  1.   

    考官是自己在工作中遇到这个了,所以问你! 你也不会,
    他就有自信了! 我的部门经理面试我是曾经问我“.net” 是什么?我现在正考虑辞职呢! 
    考官也不容易! 原谅他把 
      

  2.   

    这个能用正则表达式做?要让正则表达式来数括号?下面的逗号移一个位置结果就不一样了。aaa[bbb[ccc,ddd[eee,fff]],ggg[hhh,iii]]aaa[bbb[ccc,ddd[eee,fff],ggg[hhh,iii]]]
      

  3.   


    import java.util.*;
    import java.util.regex.*;
    public class Test1 {
    public static void main(String[] args){
    String str = "aaa[bbb[ccc,ddd[eee,fff]],ggg[hhh,iii]]"; 
    //String x="[a-z]{3}";
    Pattern pattern=Pattern.compile("[a-z]{3}\\[([a-z]{3}\\[[a-z]{3},([a-z]{3}\\[[a-z]{3},[a-z]{3}\\])\\]),[a-z]{3}\\[[a-z]{3},[a-z]{3}\\]\\]");
    Matcher matcher=pattern.matcher(str);
    System.out.println(matcher.matches()); //这行不加会报错 why? for(int i=0;i<=matcher.groupCount();i++){
    System.out.println(matcher.group(i));
    //第二组应该匹配ddd[eee,fff] ggg[hhh,iii]这两个 但是不知道如何返回
    所以ggg[hhh,iii]不知道如何弄出来 当然可以再表示式可以再加一部分 但是感觉没意义
    }
    }
    }
    结果
    true
    aaa[bbb[ccc,ddd[eee,fff]],ggg[hhh,iii]]
    bbb[ccc,ddd[eee,fff]]
    ddd[eee,fff]
      

  4.   

    感觉Matcher.group(int group)应该返回一个String[]才对 api上是String
    哈哈 发现我现学现卖的能力还不错
      

  5.   

    ninesea 谢谢你咯~!
    你好像把表达式给写死了,实际上考官告诉我 str 不是固定的,可以是任意长度的 xxx[xxx,xxx] 形式的字符串.
      

  6.   

    刚刚又想了一下 我那样确实很SB 呵呵 好像不需要用组 我是看到你这个题目好玩刚学的正则表达式
    xxx[xxx,xxx[xxx[xxx[xxx,xxx[ 这种头部好匹配 (([a-z]{3}\\[)+[a-z]{3},)+
    就是后面的]]]]不知道怎么弄 不知道怎么去嵌套我也在想
    //String str ="aaa[bbb[ccc,ddd[eee[ooo,ppp],fff[xxx,yyy[mmm,nnn]]]],ggg[hhh,iii]]";
    这种更通用的公式不过没想出来
      

  7.   

    且 xxx 不一定是 3个长度,可以任意
      

  8.   

    找了这样一个帖子 不知道java支不支持这种嵌套 要不然也只能表达出有限层1. 表达式的递归匹配
        有时候,我们需要用正则表达式来分析一个计算式中的括号配对情况。比如,使用表达式 "\( [^)]* \)" 或者 "\( .*? \)" 可以匹配一对小括号。但是如果括号 内还嵌有一层括号的话 ,如 "( ( ) )",则这种写法将不能够匹配正确,得到的结果是 "( ( )" 。类似情况的还有 HTML 中支持嵌套的标签如 "<font> </font>" 等。本节将要讨论的是,想办法把有嵌套的的成对括号或者成对标签匹配出来。匹配未知层次的嵌套:    有的正则表达式引擎,专门针对这种嵌套提供了支持。并且在栈空间允许的情况下,能够支持任意未知层次的嵌套:比如 Perl,PHP,GRETA 等。在 PHP 和 GRETA 中,表达式中使用 "(?R)" 来表示嵌套部分。    匹配嵌套了未知层次的 "小括号对" 的表达式写法如下:"\(  ([^()]  |  (?R))*  \)"。    <?php preg_match("/<div[^>]*>([^<]|(?R))*?<\/div>/", "<div>a<div>b</div>c</div>", $matches); echo "$matches[0]\n"; ?>匹配有限层次的嵌套:    对于不支持嵌套的正则表达式引擎,只能通过一定的办法来匹配有限层次的嵌套。思路如下:    第一步,写一个不能支持嵌套的表达式:"\( [^()]* \)","<font>((?!</?font>).)*</font>"。 这两个表达式在匹配有嵌套的文本时,只匹配最内层。    第二步,写一个可匹配嵌套一层的表达式:"\( ([^()] | \( [^()]* \))* \)"。这个表达式在匹配嵌套层数大于一时,只能匹配最里面的两层,同时,这个表达式也能匹配没有嵌套的文本或者嵌套的最里层。    匹配嵌套一层的 "<font>" 标签,表达式为:"<font>((?!</?font>).|(<font>((?!</?font>).)*</font>))*</font>"。这个表达式在匹配 "<font>" 嵌套层数大于一的文本时,只匹配最里面的两层。    第三步,找到匹配嵌套(n)层的表达式 与 嵌套(n-1)层的表达式之间的关系。比如,能够匹配嵌套(n)层的表达式为:    [标记头]  ( [匹配 [标记头] 和 [标记尾] 之外的表达式] | [匹配 n-1 层的表达式] )*  [标记尾]    回头来看前面编写的“可匹配嵌套一层”的表达式:  \( ( [^()] | \(([^()])*\) )* \) 
    <font> ( (?!</?font>). | (<font>((?!</?font>).)*</font>) )* </font> 
                  
    PHP 和 GRETA 的简便之处在于,匹配嵌套(n-1)层的表达式用 (?R) 表示: 
    \( ( [^()] | (?R) )* \)     第四步,依此类推,可以编写出匹配有限(n)层的表达式。这种方式写出来的表达式,虽然看上去很长,但是这种表达式经过编译后,匹配效率仍然是很高的。==============================================================================================
    api上有段文字参悟不透与 Perl 5 相比较 
    Pattern 引擎用有序替换项执行传统上基于 NFA 的匹配,与 Perl 5 中进行的相同。 此类不支持 Perl 构造: 条件构造 (?{X}) 和 (?(condition)X|Y)、 嵌入式代码构造 (?{code}) 和 (??{code})、嵌入式注释语法 (?#comment) 和 预处理操作 \l \u、\L 和 \U。此类支持但 Perl 不支持的构造: Possessive 数量词,它可以尽可能多地进行匹配,即使这样做导致所有匹配都成功时也如此。 字符类并集和交集,如上文所述。与 Perl 的显著不同点是: 在 Perl 中,\1 到 \9 始终被解释为 Back 引用;如果至少存在多个子表达式,则大于 9 的反斜线转义数按 Back 引用对待,否则在可能的情况下,它将被解释为八进制转义。在此类中,八进制转义必须始终以零开头。在此类中,\1 到 \9 始终被解释为 Back 引用,较大的数被接受为 Back 引用,如果在正则表达式中至少存在多个子表达式的话;否则,分析器将删除数字,直到该数小于或等于组的现有数或者其为一个数字。 Perl 使用 g 标志请求恢复最后匹配丢失的匹配。此功能是由 Matcher 类显式提供的:重复执行 find 方法调用可以恢复丢失的最后匹配,除非匹配器被重置。 在 Perl 中,位于表达式顶级的嵌入式标记对整个表达式都有影响。在此类中,嵌入式标志始终在它们出现的时候才起作用,不管它们位于顶级还是组中;在后一种情况下,与在 Perl 中类似,标志在组的结尾处还原。红色的“Back 引用”和“嵌入式标志”指的是什么 如何使用?
      

  9.   

    Back 引用表示再次引用前面的捕获组,比如表达式:(123)\1,匹配“123123”,但不能匹配“123456”,其中的\1是再次引用前面编号为1的捕获组(用括号包起来的叫捕获组,除“(?)”这种形式之外)。嵌入式标志是一些影响匹配模式的非捕获组模式,比如表达式:[a-z]+ 只能匹配 abc,如果采用不区分大小写匹配的话,
    改为 (?i:[a-z]+) 或者是 (?i)[a-z]+ 这样就可以匹配 ABC 了。其中(?i)就是嵌入式标志,这种形式表
    示打开不匹配大小写模式,还可以用 (?-i) 这种是关闭大小写模式,还可以用 (?i:XXXX) 指定 XXXX 不区
    分大小写模式。Java 中支持的内嵌标志表达式有:i d m s u x 共计6个。
      

  10.   

    答案是 :不可能
    因为这不是正则,而是CFG
    正则是不能处理类似镜像的结构的(比如说 [*]*, 且'['跟']'的数目相等)
      

  11.   

    突然发现一个问题:为什么[\w]+来处理abcdef会只是得到abcdef,而不是a
    ab
    abc
    abcd
    abcdef呢,有没有高手能得到我要的结果啊?
      

  12.   

    我的意思是,abcdef中

    ab 
    abc 
    abcd 
    abcdef 
    都是符合 [\w]+ 的规则的啊,为什么Matches里面只是列出一个 abcdef 呢?
      

  13.   

    匹配好的就过去了,不会再从头开始了。+ 是贪婪的,就是所有所字符串一口吃掉,看看是否匹配,如果不匹配,就吐出来一个继续,如果匹配的话就接着往下找。而 +? 是勉强的,即从左边开始一次吃掉一个字符,看看是否与模式匹配,匹配就继续找一下个,不匹配则再吃掉一个字符再来比较。如果采用 \w+? 的话,会出来:
    a
    b
    c
    d
    e
    f
    但绝对不会出来
    a  
    ab  
    abc  
    abcd  
    abcdef  
    那么多的。
      

  14.   

    似乎还不止那么多种
    bcdef
    cdef
    def
    ef
    f
    bcde
    bcd
    cde
    bc
    cd
    b
    c
    d
      

  15.   

    正则表达式是作为程序员的七种基本技能之一的,这七种技能是:1,数组、字符串与哈希表
    2,正则表达式
    3,调试
    4,两门语言
    5,一个开发环境
    6,SQL 语言
    7,编写软件的思想我是从2007年第3期的《程序员》杂志上看到的。
      

  16.   


    原来如此。 以前DOS年代,我只知道通配符*,? 觉得DOS做的不错呢  上面的第2项我今年第8年工作经验,居然也没有碰到过 所以不知道。
    用证则表达式查找字符串,估计是比较高深?的用法
      

  17.   

    出这总面试题的公司也有问题!!
    人家去面试 本来就挺紧张的  弄个这样的题 不是难为人家吗? 这样的题 能考出面试者的水平? 还是那个公司只想要“书呆子”类型的员工?
    我觉得,正则表达式也没有一个人背全的  真正用到的时候翻书边看边解决  这样的到了卷面上我是100%解不了
    刚刚google搜索了一下正则表达式, 已经学会一些了 
      

  18.   

    嘿嘿,估计DOS中的通配符就是从正则表达式中汲取的吧。这几项是杂志选出来的,没有什么效力的只是参考参考,嘿嘿~~估计是现在所有的语言都支持正则表达式了,所以会被选上吧。当然了,
    正则表达式不是时时刻刻都碰得到的,有适用场合吧。像我原来做的根据日志文件来统计站点的时段流量就很有用处了,用正
    则表达式抽取其中的URL和时间什么的。
      

  19.   

    不过正则表达试确实是比较神奇的东西,还有javascript也是
      

  20.   

    >像我原来做的根据日志文件来统计站点的时段流量就很有用处了,用正 
    >则表达式抽取其中的URL和时间什么的。从网页里查找所有连接,资源等的时候应该很有用处 恩 渐渐的我也对正则表达式感兴趣了!!
    楼主虽然你是没有答上面试题(不过不用伤心,这样的公司肯定不是什么高手云集的地方),但是你的帖子唤醒了一批梦中人啊
      

  21.   

    想了下,没想出来,试着用迭代实现import java.util.ArrayList;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    public class RegexpTest {

    public static void main(String[] args){
    StringBuffer sb = new StringBuffer("aaaa[bbb[ccc,dddd[eee,fff]],gg[hhh,iii]]"); 
    Pattern pattern = Pattern.compile("[^\\[\\],]+?\\[[^\\[\\]]+?,[^\\[\\]]+?\\]");
    List<String> resultList = new ArrayList<String>();

    while(find(pattern, sb, resultList)){
    //do something here
    }
    format(resultList);
    for(int i=0;i<resultList.size();i++){
    System.out.println(resultList.get(i));
    }
    }

    private static boolean find(Pattern pattern, StringBuffer sb, List<String> resultList){
    Matcher matcher = pattern.matcher(sb);

    boolean found = false;
    if(matcher.find()){
    found = true;
    String foundString = matcher.group();
    sb.replace(matcher.start(), matcher.end(), "{"+resultList.size()+"}");
    resultList.add(foundString);
    }
    return found;
    }

    private static void format(List<String> resultList){
    for(int i=0;i<resultList.size();i++){
    String s = resultList.get(i);
    for(int j=0;j<i;j++){
    s = s.replaceAll("\\{"+j+"\\}", resultList.get(j));
    }
    resultList.set(i, s);
    }
    }
    }
      

  22.   

    ((\w+\[\w+,?)+\w+\]{0,}),?((\w+\[\w+,?)+\w+\]{0,})?
      

  23.   

    我记得java的regex是不支持任意层级的递归匹配的
      

  24.   

    回复4楼
    因为没执行matcher.matches(),即未执行“匹配动作”,matcher.groupCount()无法执行
      

  25.   


    public static void main(String[] args) {
    String a = "aaa[bbb[ccc,ddd[eee,fff]],ggg[hhh,iii]]";
    findMatcher(a);
    }

    private static final Pattern pa = Pattern.compile("[a-z]+\\[(.+\\])");
    static void findMatcher(String input) {
    Matcher m = pa.matcher(input);
    if(m.find()) {
    String outer = m.group(0);
    String inner = m.group(1);

    System.out.println("match str=>"+outer);
    findMatcher(inner);
    } else {
    return;
    }

    }
      

  26.   

    http://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/003/onion/66.gif