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

波斯语字符串序列化中String.contains匹配失败求助

解决波斯语字符串contains()方法匹配失败的问题

我之前处理RTL(从右到左)语言字符串的时候,也碰到过一模一样的问题——明明视觉上字符串是包含关系,但contains()就是返回false,核心原因基本都是Unicode规范化不一致在搞鬼。

为什么会出现这个问题?

波斯语的部分字符存在两种Unicode表示形式:

  • 一种是预组合字符:比如字符"ک"直接用单个码点U+06A9表示
  • 另一种是基础字符+组合标记:用基础字符U+0643加上组合标记U+0650来表示,视觉上和预组合的"ک"完全一样,但底层编码是两个字符

contains()方法是严格匹配字符编码的,所以哪怕看起来一样,编码不同就匹配不上。

解决方案:统一Unicode规范化格式

Java自带的Normalizer类可以帮我们把字符串转换成统一的规范化形式,推荐用NFC(预组合形式),步骤如下:

  1. 先导入Normalizer类:
import java.text.Normalizer;
  1. 在匹配前对两个字符串做规范化处理:
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    String s = charSequence.toString().trim();
    // 对目标字符串和搜索字符串做Unicode规范化
    String normalizedFirstName = Normalizer.normalize(structuresMain.get(i).getFirstName(), Normalizer.Form.NFC);
    String normalizedQuery = Normalizer.normalize(s, Normalizer.Form.NFC);
    
    if (normalizedFirstName.contains(normalizedQuery)) {
        // 执行你的业务逻辑
    }
}

如果还是不行?检查隐藏的控制字符

有时候波斯语字符串会混入双向控制字符(比如U+200E、U+200F),这些字符看不到,但会占用字符串长度,影响匹配。可以尝试移除这些控制字符:

// 移除所有不可见的控制字符
String cleanFirstName = normalizedFirstName.replaceAll("\\p{C}", "");
String cleanQuery = normalizedQuery.replaceAll("\\p{C}", "");

if (cleanFirstName.contains(cleanQuery)) {
    // 执行你的业务逻辑
}

先试试规范化的方法,绝大多数情况下这个就能解决问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:55:09