0

我需要构建一个方法来检查字符串是否具有以下格式:

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

但我不确定什么是最好/更简单的方法来做到这一点。我应该遍历字符串还是可以使用 Pattern/Matcher 类?

一些建议或一段代码将不胜感激。

编辑

问题是字符串可能以错误的格式出现,因此该方法会返回错误...接下来,我将展示一些示例,说明可以返回什么以及应该返回什么:

[{...},{...},{...}]--> 返回有效;

[{...},{...}]--> 返回有效;

[{...},{...},{...},{...}]--> 返回有效;

[...},{...},{...},{...}]--> 返回错误;

[{...},{...}{...}]--> 返回错误;

[{...},{...},{...},{...}--> 返回错误;

[{...,{...},{...},{...}]--> 返回错误;

[{...},{...},,{...}]--> 返回错误;

[asd{...},{...},{...},{...}]--> 返回错误;

4

3 回答 3

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

所以这是第三个没有正确处理的案例,即

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

这确实需要负前瞻,即正则表达式{*},不应该匹配 a{如果它出现在 after{和 before }

于 2013-02-26T18:14:32.923 回答
1

编辑以反映表示不包含“[”、“]”或“{”的任意字符串的点

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

如果这看起来令人生畏,那可能更多是由于 Java 字符串字符转义而不是正则表达式本身。如果没有所有转义(必需),它看起来像:

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

并通过空间分隔逻辑分组来进一步澄清:

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

第一个和最后一个字符是开始/结束 '[' 和 ']' 的文字匹配。第二个字符表示必需的开头文字“{”,然后是一个字符类表达式,表示除“[”、“]”或“{”之外的任意(零个或多个)字符数,最后是源字符串中第一个大括号分组的结束文字“}”。

然而,之后可能会有额外的花括号分组,因此括号中的表达式会重复第一个并带有前面的文字逗号,并且整个表达式可能会重复零次或多次。

因此,如果这使得它更易于阅读或维护,您可以在代码中表达如下:

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

String regex = "\\[" + subgrp + optionalRepeatSubgrp + "]";
于 2013-02-26T17:53:35.137 回答
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 回答