为何该正则表达式在Android 5.1崩溃,仅在6.0及以上版本正常?
问题原因与解决方案
这个崩溃的核心原因是Android 5.1(API 22)不支持Java 7引入的(?<name>...)风格命名捕获组语法。
具体解释:
Android的正则表达式引擎在不同版本存在明显差异:
- Android 8.0(API 26)及以上版本,正则引擎更新为支持Java 7+语法的版本,包含
(?<name>...)这种命名捕获组写法; - 而Android 5.1(API 22)使用的是旧版ICU正则引擎,仅支持Perl风格的命名捕获组语法
(?'name'...),所以当你用(?<name>开头的语法时,引擎会判定为非法语法,直接抛出PatternSyntaxException。
另外,你的正则表达式里还有一个小瑕疵:'[^']*'+末尾的+是多余的,它会匹配一个或多个单引号,可能导致意外匹配(比如'abc''def'会被当成一个value),正确的单引号包裹内容的写法应该是'[^']*'。
修复方案
方案1:兼容低版本的命名捕获组写法
把命名捕获组的语法换成(?'name'...)的形式,这样在Android 5.1及更高版本都能正常工作:
Pattern pattern = Pattern.compile("(?'name'\\b\\w+\\b)\\s*=\\s*(?'value'\"[^\"]*\"|'[^']*')");
使用时依然可以通过名称获取分组内容,比如matcher.group("name")和matcher.group("value")。
方案2:使用编号捕获组(兼容性最好)
如果不需要命名捕获组,直接用传统的编号分组写法,所有Android版本都支持:
Pattern pattern = Pattern.compile("\\b(\\w+)\\b\\s*=\\s*(\"[^\"]*\"|'[^']*')");
获取内容时通过分组编号:matcher.group(1)对应name,matcher.group(2)对应value。
内容的提问来源于stack exchange,提问作者Bogdan Martynov
相关产品推荐
相关产品推荐

