编写环境:
Windows 7 X64,JDK 1.7(7.0) X64
工程版本:
J2SE 1.5(5.0)我在此环境编写了一个小东西、打包成jar包、本地运行成功、但是发给别人运行后竟然提示正则表达式编译错误目标运行环境:
WIN XP X86,JDK 1.6(6.0) X86运行后提示:
Exception in thread "main" java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index 27
nick-name="(?<username>[^"]+)"相关代码: Pattern ptnNickName = Pattern
.compile("nick-name=\"(?<username>[^\"]+)\"");这个正则表达式妥妥的是没有问题的呀?为何在别人的机器上运行会提示正则错误?
难道不同版本JDK对正则的实现不同?但是我指定工程版本是1.5的、那理论上不是应该都是向下兼容的、那不都一样了吗?

解决方案 »

  1.   

    不同jdk对正则支持确实是不一样的,但理论上来说高版本只会修复bug,增强功能
      

  2.   

    工程版本1.5
    我写的JDK1.7
    运行的JDK1.6在运行的地方提示编译错误、而且觉得这个正则表达式应该都支持的...另外还有一个地方、我封装了这样的一个方法public static ResponsePackage doPost(String reqUrl, Map parameters,
    String recvEncoding, RequestPackage requestPackage) {
    HttpURLConnection url_con = null;
    String responseContent = null;
    ResponsePackage result = new ResponsePackage(); try {
    StringBuffer params = new StringBuffer();
    for (Iterator iter = parameters.entrySet().iterator(); iter
    .hasNext();) {
    Entry element = (Entry) iter.next();
    params.append(element.getKey().toString());
    params.append("=");
    params.append(URLEncoder.encode(element.getValue().toString(),
    HttpRequestProxy.requestEncoding));
    params.append("&");
    } if (params.length() > 0) {
    params = params.deleteCharAt(params.length() - 1);
    } URL url = new URL(reqUrl);
    url_con = (HttpURLConnection) url.openConnection();
    url_con.setDoOutput(true);
    url_con.setDoInput(true);
    HttpURLConnection.setFollowRedirects(true);
    url_con.setInstanceFollowRedirects(true); HttpRequestProxy.setRequestPackage(url_con, requestPackage); url_con.setRequestMethod("POST");
    url_con.setConnectTimeout(connectTimeOut);
    url_con.setReadTimeout(readTimeOut); byte[] b = params.toString().getBytes();
    url_con.getOutputStream().write(b, 0, b.length);
    url_con.getOutputStream().flush();
    url_con.getOutputStream().close();
    url_con.connect(); InputStream in = url_con.getInputStream();
    result.cookies = HttpRequestProxy
    .getCookie(url_con, requestPackage);
    BufferedReader rd = new BufferedReader(new InputStreamReader(in,
    recvEncoding));
    String tempLine = rd.readLine();
    StringBuffer tempStr = new StringBuffer();
    String crlf = System.getProperty("line.separator");
    while (tempLine != null) {
    tempStr.append(tempLine);
    tempStr.append(crlf);
    tempLine = rd.readLine();
    }
    responseContent = tempStr.toString(); // result.cookies = url_con.getHeaderField("set-cookie"); result.client = requestPackage.client; rd.close();
    in.close();
    } catch (IOException e) {
    System.out.println("doPost Exception:" + e.getMessage());
    } finally {
    if (url_con != null) {
    url_con.disconnect();
    }
    } result.responseHtml = responseContent; return result;
    }
    在我编写的环境一切正常、在目标环境(JDK1.6)下面、在执行到InputStream in =url_con.getInputStream();这一行的时候抛出异常、是文件找不到(但是我确定网络资源是存在的、而且浏览器里也是能打开的)、同样这也是为什么呢?这又该如何解决呢?
      

  3.   

    ...........jdk1.7的编译的可能有1.7的新特性。 
    可能不能在1.5下欲行
      

  4.   

    ...那按照这样说 创建工程时选择版本有何意义?Java所谓的跨平台不是也很不靠谱么、同平台下 代码兼容性都不是那么靠谱、真相真的是这样么?
      

  5.   

    jdk 1.7目前bug还是太多,建议还是使用1.7以下。当然,高版本应该乡下兼容地版本
      

  6.   

    我测试了下,我所拥有的版本hotspot与IBM J9 的1.5,1.6都支持环视中的+与*了,小版本号1.5的是22吧,1.6的也是二十几,IBM的版本忘记了倒是android2.1的那个android.jar不支持,回想了下我是在android上碰到不支持*与+的情形
    不知道楼主的出错的运行具体环境是什么样的
      

  7.   

    你的工程是1.5的,但是开发测试环境是1.7的,所以没错,因为1.7修正了很多正则的bug
    其实LZ是想对捕获的用一个组名来记录,也就是(?<groupname>)的方式,通过${groupname}来读取,可能1.7以前的版本对这样的支持不好,导致正则解析出错,
    "nick-name=\"(?<username>[^\"]+)\""; 改成 "nick-name=\"([^\"]+)\""; 用$1来读取可能兼容性更好一些 
      

  8.   

    对于项目管理来说,必须尽量保证开发环境和生产环境一致。即便实在做不到,也保证开发环境版本低于生产环境。但楼主反其道而行,风险太大了:
    编写环境:Windows 7 X64,JDK 1.7(7.0) X64
    运行环境:WIN XP X86,JDK 1.6(6.0) X86
      

  9.   

    TO 9F
    我的工程就是最简单的J2SETO 10F
    光是这个正则问题 还是有办法变通的、比如就是命名分组改成用编号访问、不过这样的现象、让我着实很奇怪TO 11F
    我本地编写的环境是1.7、可我工程版本是1.5、那不就是1.5的么?工程版本低于JDK版本应该就可以正常运行的不是吗?那样的话我编写的环境(1.7)和运行的环境(1.6)都高于工程版本(1.5)了、那么按照我的理解、应该是运行结果是一致的、不然不就不符合Java的“一次编译 到处运行”的说法了吗?
      

  10.   


    就是eclipse里新建工程的时候 应该有个选项让你选择使用的JDK版本吧?
      

  11.   

    经过9楼qybao提示,我发现我前面错了我前面将LZ的正则当成环视了,因为肯定逆序环视就是长的(?<=....)这个样子我查了下java的命名捕获情况,是在jdk1.7才支持的http://hi.baidu.com/pangjuntaoer/item/cdefb2d21e0550b232db906f楼主是用jdk1.7开发,无论编译级别是否是1.5,默认运行的环境还是jdk1.7
      

  12.   

    楼主这个应该算是向上不兼容吧,是在用1.5的jdk尝试去解释以1.7的标准写的内容,老的无法理解新的。
      

  13.   

    哦三楼已经说了前面的解释应该是间接原因,直接原因是1.5的正则表达式语法无法接受这个表达式Exception in thread "main" java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index 27
    nick-name="(?<username>[^"]+)"look-behind group不支持 没有明显最大长度的 表达式含有导致不确定长度量词+ *等
      

  14.   

    其实  这个 运行的版本  是可以改变的本地版本:  指的就是 本地安装的JDK, eclipse默认运行的是这个工程版本:  指的是  本工程下运行的JDK 其中JDK是解压好的,只需要  导入就OK了至于1.7  还没用过,只需要  在eclipse工程运行的时候, 自己 切换一下JDK 运行就OK了
      

  15.   

    *和+ 解析方式不一样不过JDK,最好是同一个版本,,,不同版本兼容性不一样就像jdk1.4和jdk1.5 差别就很大1.7现在很难说,基本不用
      

  16.   

    (?<username>[^\"]+)这个是命名捕获组的语法,只有 JDK 1.7 才支持!PS:你这里根本没必要用到这样的语法啊?如果用了这种命名捕获组的话,一般会有反向引用 \k<username> 的引用才有意义!