java 正则表达式报错:Look-behind group does not have an obvious maximum length near index

Cooking Regex微信公众号
正则表达式学习

 

一、报错如下

 

二、源码如下(这是在解决网友遇到的问题时写的小demo时遇到的)

package ls.regex.demo;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexDemo {

	/*
	 * 需要把“select ID as 编号, TITLE as 标题 from table_a”
	 * 这样的sql语句中as前的ID和TITLE取出来放在string数组A里面, as后面的编号和标题放在string数组B里面,
	 */
	public static void main(String[] args) {

		String input = "select ID          As  编号, TITLE as   标题 from table_a";
		String regex = "\\w+(?=\\s+as\\s+)";// 匹配as之前的字段
		// String regex2="(?<=\\s{1,50}as\\s{1,50})[\\w[\u4E00-\u9FA5]]+";//匹配as之后的字段(正确匹配)
		String regex2 = "(?<=\\sas\\s+)[\\w[\u4E00-\u9FA5]]+";// 匹配as之后的字段(报错)
		System.out.println("输入的字符串为:" + input);
		String[] arrA = matcherWorld(input, regex);
		String[] arrB = matcherWorld(input, regex2);
		print(arrA, "as之前的字段为");
		print(arrB, "as之后的字段为");
	}

	/**
	 * 打印
	 * 
	 * @param arr
	 * @param message
	 */
	public static void print(String[] arr, String message) {
		if (arr != null && arr.length > 0) {
			StringBuilder sb = new StringBuilder();
			sb.append(message + ":");
			for (String ele : arr) {
				sb.append(ele).append(",");
			}
			System.out.println(sb.deleteCharAt(sb.length()-1));
		}
	}

	/**
	 * 匹配函数
	 * 
	 * @param input
	 * @param regex
	 * @return
	 */
	public static String[] matcherWorld(String input, String regex) {
		// CASE_INSENSITIVE表示不区分大小写
		Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(input);
		StringBuffer result = new StringBuffer();
		while (m.find()) {
			result.append(m.group() + ",");
		}
		return result.toString().split(",");
	}

}
 

三、原因分析

查看了 一下java的Pattern.class的源码
 
①当java正则表达式是向前查找模式时的处理:
这边可以看到只有一个case '=':,后面什么都没进行处理。因此向前匹配可以不用具体写出字符的最大长度
 
②当java正则表达式是向后查找模式时的处理:
可以看到这边进行了很多处理,在这里报错:
 if (info.maxValid == false) {
                    throw error("Look-behind group does not have "
                                + "an obvious maximum length");
                }

说明info.maxValid验证不通过,从这边可以猜测当正则表达式为向后查找模式时,用来当条件的正则,既(?<xxx)里面的xxx如果有限度长度的话,不能直接用[*?+]这三种不确定的长度来限度,而是需要写出具体的最大长度

四、解决

后来我把向后查找模式
	String regex2 = "(?<=\\sas\\s+)[\\w[\u4E00-\u9FA5]]+";

改为有具体最大长度
String regex2="(?<=\\s{1,50}as\\s{1,50})[\\w[\u4E00-\u9FA5]]+";

就可以正常运行了
 

五、总结

像以下这种写法虽然不会报错,但不能正确匹配结果
String regex2 = "(?<=\\s+as\\s+)[\\w[\u4E00-\u9FA5]]+";

所以遇到“向后查找模式”这种情况的时候,在不影响业务需求的时候,可以给它定个最大长度来处理
【PS】:暂时只想到这种方法来解决这种错误。
 

六、附加

后来发现这个问题是java jdk的一个bug,我用的jdk是1.7的,登记的是1.6的,貌似目前还没有解决
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值