Существует ли способ регулярного выражения для замены набора символов другим набором (например, командой shell tr)?

Оболочкаtr Поддержка команд заменяет один набор символов другим набором. Например,echo hello | tr [a-z] [A-Z] переведуhello вHELLO.

В Java, однако, я должен заменить каждый символ индивидуально, как показано ниже

"10 Dogs Are Racing"
    .replaceAll ("0", "0")
    .replaceAll ("1", "1")
    .replaceAll ("2", "2")
    // ...
    .replaceAll ("9", "9")
    .replaceAll ("A", "A")
    // ...
;

Апач-Обще-языки библиотека предоставляет удобныйreplaceChars способ сделать такую замену.

// half-width to full-width
System.out.println
(
    org.apache.commons.lang.StringUtils.replaceChars
    (
        "10 Dogs Are Racing",
        "0123456789ABCDEFEGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
        "0123456789ABCDEFEGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    )
);
// Result:
// 10 Dogs Are Racing

Но, как вы можете видеть, иногда searchChars / replaceChars слишком длинные (также слишком скучные, пожалуйста, найдите дублированный символ, если хотите) и могут быть выражены с помощью простого регулярного выражения[0-9A-Za-z]/[0-9A-Za-z], Есть ли способ регулярного выражения для достижения этого?

 Tim Pietzcker13 июн. 2012 г., 10:52
Краткий ответ: Нет. Извините.

Ответы на вопрос(2)

Решение Вопроса

создание собственной функции полезности для использования в сочетании сreplaceChars относительно просто. Версия ниже принимает простые классы символов, без[ или же]; это не делает отрицание класса ([^a-z]).

Для вашего случая использования вы можете сделать:

StringUtils.replaceChars(str, charRange("0-9A-Za-z"), charRange("0-9A-Za-z"))

Код:

public static String charRange(String str) {
    StringBuilder ret = new StringBuilder();
    char ch;
    for(int index = 0; index < str.length(); index++) {
        ch = str.charAt(index);
        if(ch == '\\') {
            if(index + 1 >= str.length()) {
                throw new PatternSyntaxException(
                    "Malformed escape sequence.", str, index
                );
            }
            // special case for escape character, consume next char:
            index++;
            ch = str.charAt(index);
        }
        if(index + 1 >= str.length() || str.charAt(index + 1) != '-') {
            // this was a single char, or the last char in the string
            ret.append(ch);
        } else {
            if(index + 2 >= str.length()) {
                throw new PatternSyntaxException(
                    "Malformed character range.", str, index + 1
                );
            }
            // this char was the beginning of a range
            for(char r = ch; r <= str.charAt(index + 2); r++) {
                ret.append(r);
            }
            index = index + 2;
        }
    }
    return ret.toString();
}

Производит:

0-9A-Za-z : 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0-9A-Za-z : 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
 LiuYan 刘研13 июн. 2012 г., 13:32
я взгляну на исходный кодjava.util.regex.Patternи хотите извлечь часть синтаксического анализа класса символов, а затем понять, что это трудно по сравнению с написанием небольшой функции для обработки простого класса символов (просто простая группировка и диапазон). тогда ваш ответ придет :)
 13 июн. 2012 г., 15:31
@ Liuyan & # x5218; & # x7814;Pattern должен создавать конечный автомат, а не просто строку, так что это немного сложнее.
No.

(some extra characters so that SO will allow me to post my otherwise succinct answer)

Ваш ответ на вопрос