Java Regex - 拆分逗号分隔列表,但在括号内排除逗号

Posted

技术标签:

【中文标题】Java Regex - 拆分逗号分隔列表,但在括号内排除逗号【英文标题】:Java Regex - split comma separated list, but exclude commas within parentheses 【发布时间】:2013-02-09 23:43:48 【问题描述】:

我正在尝试编写将像这样拆分 Java 字符串的正则表达式:

300x250,468x60,300x400v(480x320,768x1024,100x100),400x300v,640x480v(200x200,728x90)

变成这样的:

300x250 
468x60
300x400v(480x320,768x1024,100x100)
400x300v
640x480v(200x200,728x90)

我一直在尝试\,(\()?,但这最终也选择了括号中的逗号。

任何帮助表示赞赏!

【问题讨论】:

Java splitting a string while ignoring any delimiters between brackets 的可能重复项 @jlordo - 链接的问题不是重复的。用户没有尝试平衡括号 - 只有一层,这完全可以使用正则表达式。 @Cyborgx37:如果您确定,请发布正则表达式解决方案。 Stephen C 的回答无效。 @jlordo - Pshemo 已经有了。 ,(?![^(]*\)) 在 myregexp.com 上效果很好。这是它的链接:regexr.com?33njn @Cyborgx37:重读了他答案的正则表达式部分。是的,它工作得很好。 【参考方案1】:

如果您必须使用正则表达式,您可以在 ,(?![^(]*\\)) 上拆分

如果不是,那么一个简单的迭代字符就可以解决问题

String data="300x250,468x60,300x400v(480x320,768x1024,100x100),400x300v,640x480v(200x200,728x90)";

List<String> tokens=new ArrayList<>();
StringBuilder buffer=new StringBuilder();

int parenthesesCounter=0;

for (char c : data.toCharArray())
    if (c=='(') parenthesesCounter++;
    if (c==')') parenthesesCounter--;
    if (c==',' && parenthesesCounter==0)
        //lets add token inside buffer to our tokens
        tokens.add(buffer.toString());
        //now we need to clear buffer  
        buffer.delete(0, buffer.length());
    
    else 
        buffer.append(c);

//lets not forget about part after last comma
tokens.add(buffer.toString());

String[] splitedArray=tokens.toArray(new String[tokens.size()]);

//lets test what is inside our array
for (String s : splitedArray)
    System.out.println(s);

输出

300x250
468x60
300x400v(480x320,768x1024,100x100)
400x300v
640x480v(200x200,728x90)

【讨论】:

您的示例输出非常令人困惑和误导。 :) 另外,如果它在字符类中,我认为您不需要转义开头的括号。 @Cyborgx37 希望现在不要那么混乱了 :)【参考方案2】:

akburg,重新提出这个问题以供完成,因为它有另一个未提及的简单解决方案。这种情况类似于Match (or replace) a pattern except in situations s1, s2, s3 etc。

这是我们的简单正则表达式:

\([^)]*\)|(,)

交替的左侧匹配完整的(parentheses) 标签。我们将忽略这些匹配。右边匹配并捕获第 1 组的逗号,我们知道它们是右边的逗号,因为它们没有被左边的表达式匹配。

这个程序展示了如何使用正则表达式(见online demo底部的结果):

import java.util.*;
import java.io.*;
import java.util.regex.*;
import java.util.List;

class Program 
public static void main (String[] args) throws java.lang.Exception  

String subject = "300x250,468x60,300x400v(480x320,768x1024,100x100),400x300v,640x480v(200x200,728x90)";
Pattern regex = Pattern.compile("\\([^)]*\\)|(,)");
Matcher m = regex.matcher(subject);
StringBuffer b= new StringBuffer();
while (m.find()) 
if(m.group(1) != null) m.appendReplacement(b, "SplitHere");
else m.appendReplacement(b, m.group(0));

m.appendTail(b);
String replaced = b.toString();
String[] splits = replaced.split("SplitHere");
for (String split : splits) System.out.println(split);
 // end main
 // end Program

参考

How to match (or replace) a pattern except in situations s1, s2, s3...

【讨论】:

以上是关于Java Regex - 拆分逗号分隔列表,但在括号内排除逗号的主要内容,如果未能解决你的问题,请参考以下文章

使RegEx组将行拆分为列

MySQL REGEX匹配逗号分隔列表

PHP 和 RegEx:用不在括号内的逗号(以及嵌套括号)拆分字符串

拆分由逗号分隔的 JSON blob 列表(忽略 JSON blob 中的逗号)[重复]

如何将逗号分隔的字符串拆分为字符串列表?

sql 将逗号分隔的字符串拆分为值列表(返回游标)