You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

旧Android API下PatternSyntaxException异常及功能失效问题咨询

解决Android低版本正则去除变音符号的兼容性问题

问题根源

Android不同版本的正则表达式引擎对Unicode扩展属性(如\p{IsLm}、\p{IsSk}、\p{InCombiningDiacriticalMarks})支持不一致:

  • API 28及以下:无法识别这些扩展属性,编译Pattern时直接抛出PatternSyntaxException
  • API 30:虽能编译,但正则引擎存在匹配逻辑bug,导致执行替换时误删全部内容
  • 高版本(如API32):对这些属性支持完善,因此正常工作

推荐解决方案:使用Normalizer类处理(兼容性最优)

通过Unicode规范分解的方式去除变音符号,无需依赖有兼容性问题的正则属性,API 9+即可使用:

import java.text.Normalizer;

public class StringUtils {
    public static String removeDiacritics(String input) {
        if (input == null) return null;
        // 将字符串转换为规范分解形式(NFD),变音符号会成为独立的非间距字符
        String normalized = Normalizer.normalize(input, Normalizer.Form.NFD);
        // 移除所有非间距标记(\p{Mn}是标准Unicode属性,全Android版本支持)
        return normalized.replaceAll("\\p{Mn}+", "");
    }
}

使用时直接调用:

str = StringUtils.removeDiacritics(str);

替代方案:兼容低版本的正则表达式

如果需要保留原正则的匹配范围(包含修饰符字母、修饰符符号),可针对不同API版本使用兼容的正则属性:

import android.os.Build;
import java.util.regex.Pattern;

public class MyStaticClass {
    public static final Pattern DIACRITICS_AND_FRIENDS;

    static {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // 高版本保留原正则
            DIACRITICS_AND_FRIENDS = Pattern.compile("[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+");
        } else {
            // 低版本替换为标准Unicode属性:\p{Mn}替代\p{InCombiningDiacriticalMarks}
            DIACRITICS_AND_FRIENDS = Pattern.compile("[\\p{Mn}\\p{Lm}\\p{Sk}]+");
        }
    }
}

注:若\p{Lm}或\p{Sk}在部分极低版本仍不支持,可进一步替换为对应的Unicode字符范围(如\u02B0-\u02FF\u037F-\u03FF...),但这种方式维护成本较高,优先推荐Normalizer方案。


内容的提问来源于stack exchange,提问作者EstevaoLuis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 01:03:35