使用TextView与StringBuilder实现数字上标遇匹配失败问题求助
嘿,我来帮你搞定这个问题!你遇到的matcher.find()返回false的情况,其实是两个小问题导致的,咱们一步步理清楚:
问题根源
- 文本里根本没有后缀啊!
你传入的是"1""2"这类纯数字文本,但你的代码逻辑是给已经存在的st/nd/rd/th后缀设置上标——没有后缀的话,正则当然找不到匹配项,返回false太正常了。 - 正则表达式有个小漏洞
原正则里的\d{0,10}允许前面没有数字(0个数字),这意味着单独出现的st或者nd也会被匹配,这显然不是你要的“数字后缀”效果。
针对性解决方案
根据你的实际需求,分两种场景给你调整方案:
场景1:你已经有带后缀的文本(比如"1st""2nd")
先把正则改对,确保只匹配数字后面紧跟的后缀:
// 把\d{0,10}改成\d+,要求前面必须有至少一个数字 private static final String SUPERSCRIPT_REGEX = "(?<=\\b\\d+)(st|nd|rd|th)(?=\\b)";
这样当你传入"1st"这类文本时,正则就能精准定位到"st",触发上标设置逻辑。
场景2:你想给纯数字自动加后缀并设置上标
如果你的需求是传入纯数字(比如"1""2")时,自动生成带后缀的上标文本,那得先给数字加上正确的序数词后缀,再处理上标。新增一个工具方法,再修改format逻辑:
// 新增:给数字添加对应序数词后缀的方法 private String addOrdinalSuffix(String numberText) { try { int number = Integer.parseInt(numberText); int lastDigit = number % 10; int lastTwoDigits = number % 100; // 11-13特殊处理,都用th if (lastTwoDigits >= 11 && lastTwoDigits <= 13) { return number + "th"; } switch (lastDigit) { case 1: return number + "st"; case 2: return number + "nd"; case 3: return number + "rd"; default: return number + "th"; } } catch (NumberFormatException e) { // 不是纯数字的话,直接返回原文本 return numberText; } } // 修改原format方法 public void format(TextView textView) { CharSequence originalText = textView.getText(); // 先给纯数字添加后缀 String textWithSuffix = addOrdinalSuffix(originalText.toString()); Matcher matcher = PATTERN.matcher(textWithSuffix); stringBuilder.clear(); stringBuilder.append(textWithSuffix); while (matcher.find()) { int start = matcher.start(); int end = matcher.end(); createSuperscriptSpan(start, end); } textView.setText(stringBuilder); }
测试效果
- 传入"1" → 显示为
1ˢᵗ(上标效果) - 传入"12" → 显示为
12ᵗʰ - 传入"23" → 显示为
23ʳᵈ - 传入"11" → 显示为
11ᵗʰ(符合英文序数词的特殊规则)
内容的提问来源于stack exchange,提问作者Babar Shamsi
相关产品推荐
相关产品推荐

