Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace english digit with persian digit in String except URL's

I wrote a custom TextView for persian String, this TextView should replace english digit's to persian digit's

public class PersianTextView extends TextView {

    public PersianTextView(Context context) {
        super(context);
    }

    public PersianTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public PersianTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        String t = text.toString();
        t = t.replaceAll("0", "۰");
        t = t.replaceAll("1", "۱");
        t = t.replaceAll("2", "۲");
        t = t.replaceAll("3", "۳");
        t = t.replaceAll("4", "۴");
        t = t.replaceAll("5", "۵");
        t = t.replaceAll("6", "۶");
        t = t.replaceAll("7", "۷");
        t = t.replaceAll("8", "۸");
        t = t.replaceAll("9", "۹");
        super.setText((CharSequence)t, type);
    }
}

this View work correctly, but if i set a text from HTML, the links which contain english digits will not show as link! what is the easiest way to solve problem?

like image 662
Sajad Garshasbi Avatar asked Aug 05 '15 11:08

Sajad Garshasbi


1 Answers

One needs in some form do pattern matching on links.

private static final Pattern DIGIT_OR_LINK_PATTERN =
    Pattern.compile("(\\d|https?:[\\w_/+%?=&.]+)");
// Pattern:          (dig|link                 )

private static final Map<String, String> PERSIAN_DIGITS = new HashMap<>();
static {
   PERSIAN_DIGITS.put("0", "۰");
   PERSIAN_DIGITS.put("1", "۱");
   PERSIAN_DIGITS.put("2", "۲");
   PERSIAN_DIGITS.put("3", "۳");
   PERSIAN_DIGITS.put("4", "۴");
   PERSIAN_DIGITS.put("5", "۵");
   PERSIAN_DIGITS.put("6", "۶");
   PERSIAN_DIGITS.put("7", "۷");
   PERSIAN_DIGITS.put("8", "۸");
   PERSIAN_DIGITS.put("9", "۹");
}

public static String persianDigits(String s) {
    StringBuffer sb = new StringBuffer();
    Matcher m = DIGIT_OR_LINK_PATTERN.matcher(s);
    while (m.find()) {
        String t = m.group(1);
        if (t.length() == 1) {
            // Digit.
            t = PERSIAN_DIGITS.get(t);
        }
        m.appendReplacement(sb, t);
    }
    m.appendTail(sb);
    return sb.toString();
}

P.S.

Depending on what text, it might be better to only replace digits outside HTML tags, that is between > and <.

private static final Pattern DIGIT_OR_LINK_PATTERN =
    Pattern.compile("(\\d|<[^>]*>)",
        Pattern.DOTALL|Pattern.MULTILINE);
like image 160
Joop Eggen Avatar answered Oct 03 '22 21:10

Joop Eggen