检查字符串的格式

时间:2013-02-26 16:57:06

标签: java pattern-matching

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

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

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

一些建议或一段代码将会受到赞赏。

修改

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

[{...},{...},{...}] - >返回VALID;

[{...},{...}] - >返回VALID;

[{...},{...},{...},{...}] - >返回VALID;

[...},{...},{...},{...}] - >返回ERROR;

[{...},{...}{...}] - >返回ERROR;

[{...},{...},{...},{...} - >返回ERROR;

[{...,{...},{...},{...}] - >返回ERROR;

[{...},{...},,{...}] - >返回ERROR;

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

3 个答案:

答案 0 :(得分:1)

已编辑以反映代表不包含'[',']'或'{'

的任意字符串的点
String regex = "\\[\\{[^\\[\\]{]*}(,\\{[^\\[\\]{]*})*]";

如果这看起来令人生畏,那可能是因为Java String字符转义比正则表达式本身更多。没有所有的逃逸(必需),它看起来像:

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

通过空间分隔逻辑分组来澄清更多:

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

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

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

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

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

String regex = "\\[" + subgrp + optionalRepeatSubgrp + "]";

答案 1 :(得分:1)

这似乎可以解决大部分问题,但是由于我不擅长负面预测,我无法破解下面唯一失败的案例

此代码

  1. 用空字符串
  2. 递归替换{*},模式
  3. 然后用空字符串
  4. 替换最后一个{*}
  5. 剩余的if与[]匹配,然后该字符串被认为是有效的,或者不是。
  6. 希望你能得到我在这里想做的事。

    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
    

    所以这是第三个案件没有得到正确处理,即

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

    这确实需要否定前瞻,即如果{*},位于{之后和{之前,则正则表达式}不应与{{1}}匹配。

答案 2 :(得分: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;
    }