通过逗号进行分割,但不包括括号内的内容。

3

我知道这可能又是一个关于正则表达式的话题,但尽管我搜索了,也没有得到清晰的答案。所以这就是我的问题 - 我有一个像这样的字符串:

{1,2,{3,{4},5},{5,6}}

我要移除最外层的括号(这些括号是从输入中获取的,而我不需要它们),所以现在我的代码如下:

1,2,{3,{4},5},{5,6}

现在,我需要将此字符串分割成一个元素数组,并将括号内的所有内容视为一个“无缝”的元素:

Arr[0]    1
Arr[1]    2
Arr[2]    {3,{4},5}
Arr[3]    {5,6}

我已经尝试使用前瞻来解决这个问题,但是到目前为止,我还没有成功(非常失败)。在正则表达式方面,处理这些事情的最简洁方法是什么?

3个回答

3

如果像这样的元素需要保持在一起:{{1},{2}},那么您不能这样做。原因是这种情况下的等价于解析平衡括号语言。这种语言是上下文无关的,不能使用正则表达式进行解析。处理这个问题的最好方法不是使用正则表达式,而是使用带有堆栈的for循环(堆栈可以解析上下文无关的语言)。我们可以用伪代码表示如下:

for char in input
    if stack is empty and char is ','
        add substring(last, current position) to output array
        last = current index 
    if char is '{'
         push '{' on stack
    if char is '}'
         pop from stack

这段伪代码将构造所需的数组,请注意最好循环遍历给定字符串中字符的索引,因为您需要这些来确定添加到数组中的子字符串的边界。

1
几乎接近要求,时间不够了。稍后将完成剩余部分(单个逗号是不正确的)。 正则表达式:,(?=[^}]*(?:{|$))
检查正则表达式的有效性:前往 http://regexr.com/

enter image description here

要在Java中实现这个模式,有一点不同。需要在 { 和 } 前面添加 \ 。因此,Java输入的正则表达式为:,(?=[^\\}]*(?:\\{|$))
String numbers = {1,2,{3,{4},5},{5,6}};
numbers = numbers.substring(1, numbers.length()-1);
String[] separatedValues = numbers.split(",(?=[^\\}]*(?:\\{|$))");
System.out.println(separatedValues[0]);

0

无法想出一个正则表达式的解决方案,但这里有一个非正则表达式的解决方案。它涉及解析每个逗号之前(除非是字符串中的最后一个数字)的数字(不在花括号中),并解析字符串(在花括号内),直到找到组的结束花括号。

如果找到了正则表达式的解决方案,我很乐意看到它。

public static void main(String[] args) throws Exception {
    String data = "1,2,{3,{4},5},{5,6},-7,{7,8},{8,{9},10},11";
    List<String> list = new ArrayList();
    for (int i = 0; i < data.length(); i++) {
        if ((Character.isDigit(data.charAt(i))) ||
            // Include negative numbers
             (data.charAt(i) == '-') && (i + 1 < data.length() && Character.isDigit(data.charAt(i + 1)))) {
            // Get the number before the comma, unless it's the last number
            int commaIndex = data.indexOf(",", i);
            String number = commaIndex > -1
                    ? data.substring(i, commaIndex)
                    : data.substring(i);
            list.add(number);
            i += number.length();
        } else if (data.charAt(i) == '{') {
            // Get the group of numbers until you reach the final 
            // closing curly brace
            StringBuilder sb = new StringBuilder();
            int openCount = 0;
            int closeCount = 0;
            do {
                if (data.charAt(i) == '{') {
                    openCount++;
                } else if (data.charAt(i) == '}') {
                    closeCount++;
                }
                sb.append(data.charAt(i));
                i++;
            } while (closeCount < openCount);
            list.add(sb.toString());
        }
    }

    for (int i = 0; i < list.size(); i++) {
        System.out.printf("Arr[%d]: %s\r\n", i, list.get(i));
    }
}

结果:

Arr[0]: 1
Arr[1]: 2
Arr[2]: {3,{4},5}
Arr[3]: {5,6}
Arr[4]: -7
Arr[5]: {7,8}
Arr[6]: {8,{9},10}
Arr[7]: 11

没有正则表达式的解决方案,该语言是无上下文语言。 - ShellFish
你好,我在这段代码中遇到了问题-如何使它能够处理负值-它要么删除带有负号的值,要么返回所有值。我相信这个问题可以很快解决,但我就是找不到解决方法。 - uacnix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接