字符串的简单逻辑或正则表达式

时间:2015-03-24 01:58:20

标签: java regex string

您好,我的字符串如下 -

name,number,address(line1,city),status,contact(id,phone(number,type),email(id),type),closedate

我需要输出以下内容 -

name,number,address.line1,address.city,status,contact.id,contact.phone.number,contact.phone.type,contact.email.id,contact.type,closedate

是否可以在java中使用regex。我想到的逻辑是使用字符串操作(使用子字符串,递归等)。有没有一种简单的方法来实现这一目标?我更喜欢在java中工作的正则表达式。其他建议也欢迎。 给你一个背景 上面的字符串作为查询参数,我必须找出我需要根据它选择的所有列。因此输出中的所有这些单独项都将在属性文件中具有相应的列名。

由于 帕尔

2 个答案:

答案 0 :(得分:1)

public class Main {


    public static void main(String[] args) {
        ;
        String input ="name,number,address(line1,test(city)),status,contact(id,phone(number,type),email(id),type),closedate";
        List<String> list = new ArrayList<String>(Arrays.asList(input.split(","))); // We need a list for the iterator (or ArrayIterator)
        List<String> result = new Main().parse(list);
        System.out.println(String.join(",", result));
    }

    private List<String> parse(List<String> inputString){
        Iterator<String> it = inputString.iterator();
        ArrayList<String> result = new ArrayList<>();
        while(it.hasNext()){
            String word = it.next();
            if(! word.contains("(")){
                result.add(word);
            } else { // if we come across a "(", start the recursion and parse it till we find the matching ")"
                result.addAll(buildDistributedString(it, word,""));
            }
        }

        return result;
    }

    /*
    * recursivly parse the string
     * @param startword The first word of it (containing the new prefix, the ( and the first word of this prefic
     * @param prefix Concatenation of previous prefixes in the recursion
     */
    private List<String> buildDistributedString(Iterator<String> it, String startword,String prefix){

        ArrayList<String> result = new ArrayList<>();
        String[] splitted = startword.split("\\(");
        prefix += splitted[0]+".";

        if(splitted[1].contains(")")){ //if the '(' is immediately matches, return only this one item
            result.add(prefix+splitted[1].substring(0,splitted[1].length()-1));
            return result;
        } else {
            result.add(prefix+splitted[1]);
        }

        while(it.hasNext()){
            String word = it.next();
            if( word.contains("(")){ // go deeper in the recursion
                List<String> stringList = buildDistributedString(it, word, prefix);
                if(stringList.get(stringList.size()-1).contains(")")){
                    // if multiple ")"'s were found in the same word, go up multiple recursion levels
                    String lastString = stringList.remove(stringList.size()-1);
                    stringList.add(lastString.substring(0,lastString.length() -1));
                    result.addAll(stringList);
                    break;
                }
                result.addAll(stringList);
            } else if(word.contains(")")) { // end this recursion level
                result.add(prefix + word.substring(0,word.length()-1)); // ")" is always the last char
                break;
            } else {
                result.add(prefix+word);
            }
        }
        return result;
    }
}

我为此写了一个快速解析器。可能有一些改进,但这应该给你一个想法。这只是为了获得一个工作版本。

答案 1 :(得分:0)

由于嵌套括号出现在字符串中,因此正则表达式无法完成工作。解释为什么复杂,需要在上下文无关语法中的知识。见Can regular expressions be used to match nested patterns?

我听说过这种解析可以通过回调来完成,但我相信它在Java中并不存在。

像JavaCC这样的解析器生成器可以完成这项工作,但这对于您正在描述的任务来说是巨大的过度杀伤力。

我建议您查看java.util.Scanner,并递归调用解析方法是否看到左边的paren。