您好,我的字符串如下 -
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中工作的正则表达式。其他建议也欢迎。 给你一个背景 上面的字符串作为查询参数,我必须找出我需要根据它选择的所有列。因此输出中的所有这些单独项都将在属性文件中具有相应的列名。
由于 帕尔
答案 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。