8

シェル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")
    // ...
;

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

これを行う直接的な方法はありませんが、組み合わせて使用​​する独自のユーティリティ関数を作成するの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
于 2012-06-13T11:00:21.667 に答える
5

いいえ。

(SOがそうでなければ簡潔な答えを投稿できるようにするためのいくつかの余分な文字)

于 2012-06-13T09:41:43.003 に答える