我该如何拆分","即使它有一个","在里面

时间:2015-07-21 12:39:13

标签: java

我使用以下代码进行拆分。

List<String> separatedStringList = Arrays.asList(line.split(","));

然后我解析字符串以存储到

ArrayList<String> tags;
ArrayList<String> values;

但是当我有一行如下:

abc: def,xyz: pqr, uvw: abchash<class qwerty,struct Hash<class qwerty>,struct std::equal_to<class qwerty> >::resize

分裂&#34;,&#34;导致uvw: abchash<class qwerty, struct Hash<class qwerty>, struct std::equal_to<class qwerty>>::resize部分出现问题。

如何解决这个问题?

继续问题here

3 个答案:

答案 0 :(得分:0)

你可以拆分&#39;,&#39;并检查第4个字符是否为&#39;:&#39;。在这种情况下,你采取数组,如果没有,你采取数组和其他...

像这样:

String[] parts = string.split(",");
int i = 0;
while (i < parts.length) {
  if (parts[i].charAt(4) == ':') {
    //Do something with parts[i] 
    i++;
  }
  else {
    String wantedPart = parts[i];
    i++;
    while(parts[i].charAt(4) != ':' && i < parts.length) {
      wantedPart  = wantedPart + "," + parts[i];
      i++; 
    }
    //Do something with wantedPart 
  }
}

这是一般的想法。当然,如果wantPart很大,你可能想要使用StringBuilder。

答案 1 :(得分:0)

如果我正确读到这个问题你得到的问题是输入字符串格式不正确,你正在制作的键/值对的值部分中有','。

所以你期待你的输入

abc: def,xyz: pqr, uvw: abchash<class qwerty,struct Hash<class qwerty>,struct std::equal_to<class qwerty> >::resize

解析

abc: def
xyz: pqr
uvw: abchash<class qwerty,struct Hash<class qwerty>,struct std::equal_to<class qwerty> >::resize

但它正在解析为

abc: def
xyz: pqr
uvw: abchash<class qwerty
struct Hash<class qwerty>
struct std::equal_to<class qwerty> >::resize

解决方案是将输入值修复为引用整个值字符串或使用其他分隔符为您提供一些规则。

据我所知,你基本上没有关于你进入的规则。它可以是一个关键:价值对,或者只是你在另一个问题中的例子中的价值。在这种情况下,无法区分包含逗号的值与一个值的结束和另一个值的开头之间的区别。你说这个字符串

abc:xyz uvw, def:ghi, mno:rst, ijk:efg, abc opq

应解析为

abc:xyz uvw
def:ghi
mno:rst
ijk:efg
abc opq    <-- no key, just a value

这意味着这个

abc: def,xyz: pqr, uvw: abchash<class qwerty,struct Hash<class qwerty>,struct std::equal_to<class qwerty> >::resize

可以解析成

abc: def
xyz: pqr
uvw: abchash<class qwerty,struct Hash<class qwerty>,struct std::equal_to<class qwerty> >::resize

或同样

abc: def
xyz: pqr
uvw: abchash<class qwerty
struct Hash<class qwerty>,struct std::equal_to<class qwerty> >::resize

或同样

abc: def
xyz: pqr
uvw: abchash<class qwerty
struct Hash<class qwerty>
struct std::equal_to<class qwerty> >::resize

等等

如果您有多个同等有效的答案,则需要以某种方式更改输入,以便使用正则表达式缩小正确的答案范围。

答案 2 :(得分:0)

使用基于堆栈的算法为泛型类型约束计算字符串,如下所示:

<强>代码

final String text = "abc: def,xyz: pqr, uvw: abchash<class qwerty,struct Hash<class qwerty>,struct std::equal_to<class qwerty> >::resize";

int start = 0;
Stack<Character> generics = new Stack<>();
for (int i = 0; i < text.length(); i++) {
    char c = text.charAt(i);
    switch (c) {
        case '<':
            generics.push(c);
            break;
        case '>':
            if(generics.isEmpty() || generics.pop() != '<') {
                throw new IllegalArgumentException("Invalid generic type constraints");
            }
            break;
        case ',':
            if (generics.isEmpty()) {
                System.out.println(text.substring(start, i));
                start = i + 1; //move window
            }
            break;
    }
}
if (generics.isEmpty()) {
    System.out.println(text.substring(start));
}

<强>输出

abc: def
xyz: pqr
 uvw: abchash<class qwerty,struct Hash<class qwerty>,struct std::equal_to<class qwerty> >::resize

进一步改进
上面的代码可以写成Iterable

public static Iterator<String> iterateValues(String text) {
    return new Iterator<String>() {
        int start = 0;
        Stack<Character> generics = new Stack<>();

        @Override
        public boolean hasNext() {
            return start <= text.length();
        }

        @Override
        public String next() {
            for (int i = start; i < text.length(); i++) {
                char c = text.charAt(i);
                switch (c) {
                    case '<':
                        generics.push(c);
                        break;
                    case '>':
                        if (generics.isEmpty() || generics.pop() != '<') {
                            throw new IllegalArgumentException("Invalid generic type constraints");
                        }
                        break;
                    case ',':
                        if (generics.isEmpty()) {
                            String result = text.substring(start, i);
                            start = i + 1; //move window
                            return result;
                        }
                        break;
                }
            }
            String result = text.substring(start);
            start = text.length() + 1; //move window
            return result;
        }
    };
}