8

shelltr命令支持用另一组字符替换一组字符。例如,echo hello | tr [a-z] [A-Z]将翻译helloHELLO.

但是,在 java 中,我必须单独替换每个字符,如下所示

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

apache-commons-lang库提供了一种方便的方法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]。有没有正则表达式的方法来实现这一点?

4

2 回答 2

5

不。

(一些额外的字符,这样我就可以发布我原本简洁的答案)

于 2012-06-13T09:41:43.003 回答
5

虽然没有直接的方法可以做到这一点,但构建自己的实用函数以与之结合使用replaceChars相对简单。下面的版本接受简单的字符类,没有[or ]; 它不做类否定 ( [^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
于 2012-06-13T11:00:21.667 回答