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

Java 字符串的简单逻辑或正则表达式,java,regex,string,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 我

嗨,我有一根像下面这样的线-

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
我需要输出以下内容-

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中使用正则表达式来实现这一点。我想到的逻辑是使用字符串操作(带子字符串、递归等)。有没有一个简单的方法来实现这一点?我更喜欢在java中工作的正则表达式。也欢迎提出其他建议。 给你一个背景 上面的字符串是作为查询参数出现的,我必须找出我需要根据它选择的所有列。因此,输出中的所有这些单独的项在属性文件中都有各自的列名

谢谢
Pal

因为嵌套的括号出现在字符串中,所以正则表达式无法完成这项工作。原因的解释很复杂,需要上下文无关语法的知识。看

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

像JavaCC这样的解析器生成器可以完成这项工作,但是对于您描述的任务来说,这是一个巨大的过度消耗

我建议您查看
java.util.Scanner
,无论是否看到左paren,都可以递归调用parse方法。

公共类Main{
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;
    }
}
公共静态void main(字符串[]args){ ; String input=“姓名、号码、地址(第1行,测试(城市))、状态、联系人(id、电话(号码、类型)、电子邮件(id)、类型)、关闭日期”; List List=newarraylist(Arrays.asList(input.split(“,”));//我们需要一个迭代器(或ArrayIterator)的列表 列表结果=new Main().parse(列表); System.out.println(String.join(“,”,result)); } 私有列表解析(列表输入字符串){ 迭代器it=inputString.Iterator(); ArrayList结果=新建ArrayList(); while(it.hasNext()){ String word=it.next(); 如果(!word.包含(“”){ 结果:添加(word); }否则{//如果我们遇到一个“(”,启动递归并解析它,直到找到匹配的“)” result.addAll(buildDistributedString(it,word,“”); } } 返回结果; } /* *递归地解析字符串 *@param startword它的第一个字(包含新前缀,)和这个前缀的第一个字 *@param prefix递归中先前前缀的串联 */ 私有列表buildDistributedString(迭代器it、字符串StartWorld、字符串前缀){ ArrayList结果=新建ArrayList(); String[]splitted=startword.split(“\\(”); 前缀+=拆分的[0]+>; 如果(拆分的[1].contains(“)”){//如果“(”立即匹配,则只返回这一项 结果.add(前缀+拆分的[1]。子字符串(0,拆分的[1]。长度()-1)); 返回结果; }否则{ 结果.添加(前缀+拆分[1]); } while(it.hasNext()){ String word=it.next(); if(word.contains(“(”){//深入递归 List stringList=buildDistributedString(它、字、前缀); if(stringList.get(stringList.size()-1).contains(“)”){ //如果在同一个单词中发现多个“)”,则向上执行多个递归级别 String lastString=stringList.remove(stringList.size()-1); 添加(lastString.substring(0,lastString.length()-1)); 结果.addAll(stringList); 打破 } 结果.addAll(stringList); }else如果(word.contains(“)”){//结束此递归级别 结果.add(前缀+单词.substring(0,word.length()-1));/”)始终是最后一个字符 打破 }否则{ 结果.添加(前缀+单词); } } 返回结果; } }

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

你应该提到,这只适用于java 8不确定,但我认为它也适用于java 7。即使没有,我也不认为重写不可用的部分会很困难t、
String.join()
仅在Java8中引入,OP(或其他任何人)可能不知道它,并假设您的代码不工作