今天去面试,考官出了一正则表达式的题目,一下蒙住了,各位给看看!

lazywalk 2008-03-04 03:34:40
现有一字符串:
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]

求一正则表达式,能将这个字符串分割成以上结果!
...全文
1877 45 打赏 收藏 转发到动态 举报
写回复
用AI写文章
45 条回复
切换为时间正序
请发表友善的回复…
发表回复
z1466459262 2010-05-10
  • 打赏
  • 举报
回复
.{3}\[( [^\[\],]*,[^\[\],]* |(?R)* )*\]

用这个试试
fang00y 2010-05-10
  • 打赏
  • 举报
回复
https://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/003/onion/66.gif
南南北北 2010-05-10
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 bao110908 的回复:]

正则表达式是作为程序员的七种基本技能之一的,这七种技能是:

1,数组、字符串与哈希表
2,正则表达式
3,调试
4,两门语言
5,一个开发环境
6,SQL 语言
7,编写软件的思想

我是从2007年第3期的《程序员》杂志上看到的。
[/Quote]

不会。。。
beiouwolf 2010-05-10
  • 打赏
  • 举报
回复

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;
}

}
CWORLD002 2010-05-09
  • 打赏
  • 举报
回复
用迭代能实现
zhuwen9 2010-05-09
  • 打赏
  • 举报
回复
楼上的骰子很有意思。。
luopowusheng 2010-05-09
  • 打赏
  • 举报
回复
来看回帖的~
jjjjjjjjjjay 2010-05-09
  • 打赏
  • 举报
回复
回复4楼
因为没执行matcher.matches(),即未执行“匹配动作”,matcher.groupCount()无法执行
eggno8 2010-05-09
  • 打赏
  • 举报
回复
来学习的
taigarz 2010-05-08
  • 打赏
  • 举报
回复
我记得java的regex是不支持任意层级的递归匹配的
cycloneTeam 2010-05-08
  • 打赏
  • 举报
回复
用贪婪模式
zxcv991 2010-05-08
  • 打赏
  • 举报
回复
学习一下
whlcy 2010-05-08
  • 打赏
  • 举报
回复
mark!!!!!
hehuanju 2010-05-08
  • 打赏
  • 举报
回复
((\w+\[\w+,?)+\w+\]{0,}),?((\w+\[\w+,?)+\w+\]{0,})?
jimmyshao 2008-03-06
  • 打赏
  • 举报
回复
想了下,没想出来,试着用迭代实现

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);
}
}
}
  • 打赏
  • 举报
回复
>像我原来做的根据日志文件来统计站点的时段流量就很有用处了,用正
>则表达式抽取其中的URL和时间什么的。

从网页里查找所有连接,资源等的时候应该很有用处。。。 恩 渐渐的我也对正则表达式感兴趣了!!
楼主虽然你是没有答上面试题(不过不用伤心,这样的公司肯定不是什么高手云集的地方),但是你的帖子唤醒了一批梦中人啊
ninesea 2008-03-05
  • 打赏
  • 举报
回复
找了这样一个帖子 不知道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 引用”和“嵌入式标志”指的是什么 如何使用?
shouzhi2007 2008-03-05
  • 打赏
  • 举报
回复

学习了
jinjieai4587 2008-03-05
  • 打赏
  • 举报
回复
不过正则表达试确实是比较神奇的东西,还有javascript也是
  • 打赏
  • 举报
回复
楼主的这道题根本就不能用正则表达式来解决,不知道那个公司是何用意!
加载更多回复(24)

62,617

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧