0

文字列が次の形式であるかどうかを確認するメソッドを作成する必要があります。

[{...},{...},...,{...}]

しかし、これを行うための最良/より簡単なアプローチが何であるかはわかりません。文字列を反復処理する必要がありますか、それともパターン/マッチャークラスを使用できますか?

最初にいくつかの提案やコードをいただければ幸いです。

編集

問題は、文字列が間違った形式で返される可能性があるため、メソッドがエラーを返す可能性があることです...次に、何が返され、何が返されるかを示す例をいくつか示します。

[{...},{...},{...}]->有効な値を返します。

[{...},{...}]->有効な値を返します。

[{...},{...},{...},{...}]->有効な値を返します。

[...},{...},{...},{...}]->エラーを返します。

[{...},{...}{...}]->エラーを返します。

[{...},{...},{...},{...}->エラーを返します。

[{...,{...},{...},{...}]->エラーを返します。

[{...},{...},,{...}]->エラーを返します。

[asd{...},{...},{...},{...}]->エラーを返します。

4

3 に答える 3

1

'['、']'、または'{'を含まない任意の文字列を表すドットを反映するように編集されました

String regex = "\\[\\{[^\\[\\]{]*}(,\\{[^\\[\\]{]*})*]";

これが気が遠くなるように見える場合は、正規表現自体よりもJava文字列文字のエスケープが原因である可能性があります。すべてのエスケープ(必須)がないと、次のようになります。

\[\{[^\[\]{]*}(,\{[^\[\]{]*})*]

そして、論理グループをスペースで区切ることによってさらに明確にするために:

\[   \{[^\[\]{]*}   (,\{[^\[\]{]*})*   ]

最初と最後の文字は、開始/終了'['と']'のリテラル一致です。2番目の文字は、必要な開始リテラル'{'を示し、その後に'['、']'、または'{'以外の任意の(ゼロ以上の)文字数を表す文字クラス式が続き、最後にソース文字列の最初の中括弧で囲まれたグループの終了リテラル'}'。

ただし、後で中括弧で囲まれたグループが追加される場合があるため、括弧で囲まれた式は、前にリテラルのコンマが付いた最初の式を繰り返し、この式全体が0回以上繰り返される場合があります。

したがって、これにより読みやすく、保守しやすくなる場合は、次のようにコードで表現できます。

String subgrp = "\\{[^\\[\\]{]*}";
String optionalRepeatSubgrp = "(," + subgrp + ")*";

String regex = "\\[" + subgrp + optionalRepeatSubgrp + "]";
于 2013-02-26T17:53:35.137 に答える
1

これは問題のほとんどを解決するようですが、私はネガティブな先読みがあまり得意ではないため、以下で失敗する唯一のケースをクラックすることができませんでした

このコード

  1. {*},パターンを空の文字列に繰り返し置き換えます
  2. 次に、最後の{*}文字列を空の文字列に置き換えます
  3. 残りのifがthenと一致する[]場合、その文字列は有効であるかどうかを示します。

私がここでやろうとしていることをあなたが手に入れてくれることを願っています。

public static boolean isValid(String input){

        // Iterates and replaces all but one substring that match {...},
        boolean replaced = true;
        int oldLength=0, newLength=0;
        while(replaced){
            oldLength=input.length();
            input = input.replaceFirst("\\{[a-z.]+},", "");
            newLength=input.length();
            if(oldLength==newLength)    replaced=false;
        }

        // Replaces the last {...} 
        // This one is done separately as comma should not be present in the last part 
        input = input.replaceFirst("\\{.*?}", "");

        //Then if the string remaining is just [] then it is valid
        if(input.equals("[]")){
            return true;
        } else {
            return false;
        }
    }

    public static void main(String[] args) {
        String[] input = {"[{...},{...},{...}]",
                            "[{...},{...}]",
                            "[{...},{...},{...},{...}]",
                            "[...},{...},{...},{...}]",
                            "[{...},{...}{...}]",
                            "[{...},{...},{...},{...}",
                            "[{...,{...},{...},{...}]",
                            "[{...},{...},,{...}]",
                            "[asd{...},{...},{...},{...}]"
                    };
        for (String s : input) {
            if(isValid(s)){
                System.out.println("VALID");
            } else {
                System.out.println("ERROR");
            }
        }
    }
}

これは出力します-

VALID
VALID
VALID
ERROR
ERROR
ERROR
VALID
ERROR
ERROR

つまり、正しく処理されていない最後の3番目のケースです。

 [{...,{...},{...},{...}]

これには、負の先読みが必要です。つまり、正規表現が前後にある場合は、正規表現{*},が一致しないようにする必要があります。{{}

于 2013-02-26T18:14:32.923 に答える
0

複雑な正規表現を考えるのに時間を費やすのではなく、文字列を繰り返し処理しないのはなぜですか?

public boolean isValid(String str){
        if( !str.startsWith("[") || !str.endsWith("]") )
            return false;

        if( 1 < str.length() - 2 )
            return false;

        str = str.substring(1, str.length() - 2);

        String[] array = str.split(",");
        String part;

        for( int i = 0 ; i < array.length ; i ++ ){
            part = array[i];

            if(!part.startsWith("{") || !part.endsWith("}"))
                return false;

            if( 1 < part.length() - 2 )
                return false;

            part = part.substring(1, part.length() - 2);

            if(part.contains("{") || part.contains("}"))
                return false;
        }

        return true;
    }
于 2013-02-26T18:23:02.800 に答える