java 正则表达式报错:Look-behind group does not have an obvious maximum length near index
2016-11-29 16:24
681 查看
一、报错如下
二、源码如下(这是在解决网友遇到的问题时写的小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的,貌似目前还没有解决相关文章推荐
- 正则表达式报错 PatternSyntaxException Unclosed group near index
- java正则表达式之group()
- java 正则表达式 Match 的group方法见解
- java.lang.IllegalArgumentException: Path index does not start with a "/" character
- Resolving: java.sql.Timestamp does not have a no-arg default constructor
- java正则表达式抽取html数据【macher.group(1).trim()】
- L6305W: Image does not have an entry point. (Not specified or not set due to multiple choices.)
- java正则表达式:什么是分组group()
- Java正则表达式组group()的用法
- java.lang.SecurityException: Sending SMS message: uid 10047 does not have android.permission.SEND_SM
- javax.el.PropertyNotFoundException: The class 'java.lang.String' does not have the property 'XXX'
- C# Issues and Solutions -- Method get_XXX from assembly YYYY does not have an implementation
- does not have element "configuration/configSections/sectionGroup[@name='SharePoint']" or it is invalid
- 自建Yii项目进入shell 出现Error: index.php does not exist or is not an entry script file.
- java正则表达式练习-涉及分组group()
- [笔记].怎样解决MDK中的警告:Warning: L6305W: Image does not have an entry point. (Not specified or not set due to multiple choices.)
- java.lang.SecurityException: Sending SMS message: User 10034 does not have android.permission
- JAVA 正则表达式:使用group方法计算匹配到的字符串个数
- Java 正则表达式里的 groupCount
- how to solve "java.sql.Timestamp does not have a no-arg default constructor" ? .